Portfolio optimization is an important topic in Finance. Modern portfolio theory (MPT) states that investors are risk averse and given a level of risk, they will choose the portfolios that offer the most return. To do that we need to optimize the portfolios.
To perform the optimization we will need
To download the price data of the assets
Assign random weights to the assets
Calculate daily portfolio return, sd, kurtosis, ddve, sign correlation and t df
Use the daily portfolio return, ddve, sign correlation and t df to pick up minimum risk and tangency portfolio and determine the optimal weights
Use the optimal weights of each portfolio to calculate the annualized portflio return, sd and Sharpe ratio to compare all the portfolios
Use GA to compare with the random weights algorithm
So lets begin
First lets load our packages
# list.of.packages <- c('tidyverse','tidyquant', 'plotly','timetk','GA','xtable', 'textreadr','rvest','fGarch',"dplyr", "dygraphs", "quantmod", "TTR", 'zoo', 'tseries', 'fGarch','PEIP','tidyverse','gridExtra', 'gdata', 'xtable',"dygraphs")
# new.packages <- list.of.packages[!(list.of.packages %in% installed.packages()[,"Package"])]
# if(length(new.packages) > 0) {install.packages(new.packages)}
# lapply(list.of.packages, require, character.only=T)
library('tidyverse')
library('tidyquant')
## Warning: package 'xts' was built under R version 4.3.3
## Warning: package 'quantmod' was built under R version 4.3.2
library('plotly')
library('timetk')
library('GA')
## Warning: package 'GA' was built under R version 4.3.2
library('xtable')
#library('textreadr')
library('rvest')
library('fGarch')
library("dplyr")
library("dygraphs")
library("quantmod")
library("TTR")
library('zoo')
library('tseries')
library('fGarch')
library('PEIP')
library('tidyverse')
library('gridExtra')
library('gdata')
library('xtable')
library("dygraphs")
# Load all the required functions needed get the results
## function to generate weight
# get_weights <- function(N){
# return(diff(c(0, sort(runif(N-1, min = 0, max = 1)), 1)))
# }
get_weights <- function(N){
w<- runif(N, min = 0, max = 1)
return(w/sum(w))
}
# skewness correlation
skewrho <- function(X){
skewrho.cor <- cor(X-mean(X), (X-mean(X))^2)
return(skewrho.cor)
}
# sign correlation
rho.cal<-function(X){
rho.hat<-cor(sign(X-mean(X)), X-mean(X))
return(rho.hat)
}
# volatlity correlation
rho.vol<-function(X){
rho.vol<-cor(abs(X-mean(X)), (X-mean(X))^2)
return(rho.vol)
}
Simulation study for sign correlation and volatility correlation
# simulate normal, t(2), t(3), t(4), t(5)
sample <- 8000
sim.n <- rnorm (sample) # sign correlation of a normal distribution is sqrt(2/pi)=0.7979
sim.t25 <- rt (sample, df = 2.5)
sim.t3 <- rt (sample, df = 3)
sim.t35 <- rt (sample, df = 3.5)
sim.t4 <- rt (sample, df = 4)
sim.t5 <- rt (sample, df = 5)
data <- cbind (sim.t25, sim.t3, sim.t35, sim.t4, sim.t5, sim.n)
skewrho<-apply(as.matrix(data), MARGIN=2, FUN=skewrho)
rhosign<-apply(as.matrix(data), MARGIN=2, FUN=rho.cal)
rhovol<-apply(as.matrix(data), MARGIN=2, FUN=rho.vol)
assetsummary<-data.frame(apply(data, 2, mean), apply(data, 2, sd), apply(data, 2, skewness), apply(data, 2, kurtosis), skewrho, rhovol, rhosign)
xtable(assetsummary, digits=4)
## % latex table generated in R 4.3.1 by xtable 1.8-4 package
## % Tue Sep 24 19:02:38 2024
## \begin{table}[ht]
## \centering
## \begin{tabular}{rrrrrrrr}
## \hline
## & apply.data..2..mean. & apply.data..2..sd. & apply.data..2..skewness. & apply.data..2..kurtosis. & skewrho & rhovol & rhosign \\
## \hline
## sim.t25 & -0.0040 & 1.9340 & -0.3106 & 48.0347 & -0.0439 & 0.7443 & 0.6179 \\
## sim.t3 & 0.0159 & 1.8182 & -0.8978 & 125.8054 & -0.0794 & 0.6834 & 0.6195 \\
## sim.t35 & 0.0205 & 1.4798 & 0.0329 & 6.0475 & 0.0116 & 0.8530 & 0.7014 \\
## sim.t4 & -0.0023 & 1.3873 & -0.2156 & 10.0322 & -0.0622 & 0.7708 & 0.7128 \\
## sim.t5 & -0.0067 & 1.3050 & -0.1360 & 4.2660 & -0.0544 & 0.8387 & 0.7367 \\
## sim.n & 0.0057 & 1.0127 & 0.0104 & -0.0062 & 0.0074 & 0.9339 & 0.7987 \\
## \hline
## \end{tabular}
## \end{table}
Next lets select a few stocks to build our portfolios.
We will choose some stocks.
Lets download the price data.
#Import data
mi_DBSCAN_2023_lowest_average_clustering <- read.csv("~/Desktop/PO/DBSCAN/MI/2023/mi_DBSCAN_2023_lowest_average_clustering.csv")
#remove the date column
asset_prices<-mi_DBSCAN_2023_lowest_average_clustering[,-1]
# calculate returns
ret_tidy1 = apply(asset_prices,2, log)
head(ret_tidy1)
## ETH.USD JNJ MMM T V
## [1,] 7.102317 5.129780 4.541414 2.818319 5.320976
## [2,] 7.136107 5.140609 4.563061 2.839439 5.345835
## [3,] 7.131250 5.133198 4.545407 2.843089 5.338754
## [4,] 7.146283 5.141275 4.575528 2.859610 5.369723
## [5,] 7.186552 5.115025 4.576080 2.848537 5.373619
## [6,] 7.197874 5.112630 4.586594 2.870870 5.384945
ret_tidy2 = diff(ret_tidy1)
head(ret_tidy2)
## ETH.USD JNJ MMM T V
## [1,] 0.033789247 0.010828377 0.0216470148 0.021119925 0.024858388
## [2,] -0.004856888 -0.007410973 -0.0176539801 0.003650662 -0.007080126
## [3,] 0.015033458 0.008076862 0.0301208147 0.016520822 0.030968202
## [4,] 0.040269095 -0.026250061 0.0005522516 -0.011072956 0.003895977
## [5,] 0.011321725 -0.002394989 0.0105131304 0.022332852 0.011326329
## [6,] 0.037696756 -0.001599760 0.0076968923 -0.003086468 0.004557829
ret_tidy = exp (ret_tidy2) - 1 #simple returns
#remove first row
asset_returns <- ret_tidy[-1,]
#no.of assets in the portfolio
nasset<-ncol(asset_returns)
# testing and training data sets (each data set has 252 observations)
# Divide the data set in to 3:1 (75% training and 25% testing)
# testing period - January - September (189 data points)
# training period - October - December (62 data points)
n.total<-252
n.train<- 189
train = asset_returns[1:n.train,]
test = asset_returns[-(1:(n.train)),]
##summary statistics
rhosign<-apply(as.matrix(train), MARGIN=2, FUN=rho.cal)
rhovol<-apply(as.matrix(train), MARGIN=2, FUN=rho.vol)
assetsummary<-data.frame(apply(train, 2, mean), apply(train, 2, sd), rhovol, rhosign, apply(train, 2, skewness),
apply(train, 2, kurtosis))
xtable(assetsummary, digits=4)
## % latex table generated in R 4.3.1 by xtable 1.8-4 package
## % Tue Sep 24 19:02:38 2024
## \begin{table}[ht]
## \centering
## \begin{tabular}{rrrrrrr}
## \hline
## & apply.train..2..mean. & apply.train..2..sd. & rhovol & rhosign & apply.train..2..skewness. & apply.train..2..kurtosis. \\
## \hline
## ETH.USD & 0.0018 & 0.0303 & 0.8551 & 0.7043 & 0.9948 & 5.3989 \\
## JNJ & -0.0005 & 0.0108 & 0.8876 & 0.6752 & 0.7182 & 7.3649 \\
## MMM & -0.0015 & 0.0178 & 0.8954 & 0.7041 & 0.5870 & 4.1278 \\
## T & -0.0010 & 0.0174 & 0.9085 & 0.6455 & -0.5911 & 10.3598 \\
## V & 0.0006 & 0.0101 & 0.9360 & 0.7797 & 0.2072 & 0.6578 \\
## \hline
## \end{tabular}
## \end{table}
plot(train, legend.loc=1)
## Warning in plot.window(...): "legend.loc" is not a graphical parameter
## Warning in plot.xy(xy, type, ...): "legend.loc" is not a graphical parameter
## Warning in axis(side = side, at = at, labels = labels, ...): "legend.loc" is
## not a graphical parameter
## Warning in axis(side = side, at = at, labels = labels, ...): "legend.loc" is
## not a graphical parameter
## Warning in box(...): "legend.loc" is not a graphical parameter
## Warning in title(...): "legend.loc" is not a graphical parameter
Lets calculate annualized portfolio return, risk, and gamma from the simulated portfolio returns with portfolio weights. (simulated weights)
## portfolio return, sd and gamma
## w is the random weight
## data = train or test
portfolio_info = function(w, data){
port.data <- data%*%as.vector(w)
port.cdf <- ecdf(port.data)
port.return <- mean (port.data)
port.sd <- sd (port.data)
port.signrho <- cor (port.data - port.return, sign(port.data - port.return))
# port.signrho3 <- cor (sign(port.data - port.return), (port.data - port.return)^3)
# port.skewrho <- cor (port.data - port.return, (port.data - port.return)^2)
port.volcor <- cor (abs(port.data - port.return), (port.data - port.return)^2) #volatlity correlation
port.skewness <- skewness (port.data) #mu_3/sigma^3
port.kurtosis <- kurtosis (port.data) #excess kurtosis mu_4/sigma^4 - 3
return(c(port.return, port.sd, port.volcor, port.signrho, port.cdf(port.return), port.skewness, port.kurtosis))
}
# In stat matrix and weight matrix nrow = no.of assets in the portfolio (need to change), ncol is fixed to 7 , for loop i in 1:nrow
stat<-matrix(0, nrow = nasset, ncol = 7)
weight<-matrix(0, nrow = nasset, ncol = nasset)
for (i in 1:nasset){
weight[i, ] <- get_weights(nasset)
stat[i, ] <- portfolio_info (weight[i, ], as.matrix(train))
}
xtable(weight, digits = 4)
## % latex table generated in R 4.3.1 by xtable 1.8-4 package
## % Tue Sep 24 19:02:38 2024
## \begin{table}[ht]
## \centering
## \begin{tabular}{rrrrrr}
## \hline
## & 1 & 2 & 3 & 4 & 5 \\
## \hline
## 1 & 0.1232 & 0.3013 & 0.2672 & 0.1972 & 0.1110 \\
## 2 & 0.2353 & 0.1534 & 0.2309 & 0.3196 & 0.0608 \\
## 3 & 0.2527 & 0.2964 & 0.1346 & 0.1755 & 0.1409 \\
## 4 & 0.0850 & 0.1456 & 0.2355 & 0.2850 & 0.2489 \\
## 5 & 0.2672 & 0.0199 & 0.1543 & 0.1949 & 0.3637 \\
## \hline
## \end{tabular}
## \end{table}
xtable(stat, digits = 4)
## % latex table generated in R 4.3.1 by xtable 1.8-4 package
## % Tue Sep 24 19:02:38 2024
## \begin{table}[ht]
## \centering
## \begin{tabular}{rrrrrrrr}
## \hline
## & 1 & 2 & 3 & 4 & 5 & 6 & 7 \\
## \hline
## 1 & -0.0005 & 0.0093 & 0.9524 & 0.7808 & 0.5185 & 0.1179 & -0.0472 \\
## 2 & -0.0003 & 0.0114 & 0.9359 & 0.7726 & 0.5079 & 0.1370 & 0.6074 \\
## 3 & -0.0000 & 0.0105 & 0.9042 & 0.7737 & 0.5238 & 0.4155 & 1.0733 \\
## 4 & -0.0004 & 0.0091 & 0.9362 & 0.7714 & 0.5132 & 0.0232 & 0.2266 \\
## 5 & 0.0003 & 0.0114 & 0.9235 & 0.7752 & 0.5185 & 0.3622 & 0.6064 \\
## \hline
## \end{tabular}
## \end{table}
Check for the portfolio sd can be calcualted by both the formula and sd of the simulated portfolio.
We have everything we need to perform our optimization. All we need now is to run this code on 8000 random portfolios. For that we will use a for loop.
Before we do that, we need to create empty vectors and matrix for storing our values.
#change nasset to no of assets in portfolio
num_port <- 10000
nasset <- nasset
# Creating a matrix to store the weights
all_wts1 <- matrix(nrow = num_port,
ncol = nasset)
# Creating an empty vector to store
# 8000 Portfolio returns
port_returns <- vector('numeric', length = num_port)
# Creating an empty vector to store
# 8000 Portfolio variances
port_risk.var1 <- vector('numeric', length = num_port)
port_risk.var2 <- vector('numeric', length = num_port)
port_risk.var3 <- vector('numeric', length = num_port)
port_risk.var4 <- vector('numeric', length = num_port)
port_risk.mad <- vector('numeric', length = num_port)
Sharpe_ratio.sd1 <- vector('numeric', length = num_port)
Sharpe_ratio.sd2 <- vector('numeric', length = num_port)
Sharpe_ratio.sd3 <- vector('numeric', length = num_port)
Sharpe_ratio.sd4 <- vector('numeric', length = num_port)
Sharpe_ratio.mad <- vector('numeric', length = num_port)
Next lets run the for loop 10000 times.
port.info <- matrix(0, nrow = 10000, ncol = 7)
ptm <- proc.time()
for (i in seq_along(port_returns)) {
wts <- get_weights(nasset)
# Storing weight in the matrix
all_wts1[i,] <- wts
# Portfolio returns
port.info [i, ]<- portfolio_info (wts, as.matrix(train))
# Storing Portfolio Returns values
port_returns[i] <- port.info[i, 1]
# Creating and storing portfolio risk
port_risk.var1 [i] <- port.info[i, 2]
port_risk.var2 [i] <- sqrt(1 - port.info[i, 3]^2)*port.info[i, 2]
port_risk.var3 [i] <- sqrt(1 - port.info[i, 4]^2)*port.info[i, 2]
port_risk.var4 [i] <- sqrt(1 - port.info[i, 3]^2)*sqrt(1 - port.info[i, 4]^2)*port.info[i, 2]
port_risk.mad [i] <- 2*port.info[i, 2]*port.info[i, 4]*sqrt(port.info[i, 5]*(1-port.info[i, 5]))
# Creating and storing Portfolio Sharpe Ratios
# Assuming 0% Risk free rate
Sharpe_ratio.sd1 [i] <- port_returns[i]/port_risk.var1 [i]
Sharpe_ratio.sd2 [i] <- port_returns[i]/port_risk.var2 [i]
Sharpe_ratio.sd3 [i] <- port_returns[i]/port_risk.var3 [i]
Sharpe_ratio.sd4 [i] <- port_returns[i]/port_risk.var4 [i]
Sharpe_ratio.mad [i] <- port_returns[i]/port_risk.mad [i]
}
proc.time()-ptm
## user system elapsed
## 12.888 0.300 18.692
port.info.data <- as.data.frame(port.info)
ggplot(port.info.data, aes(x=V6, y=V1)) + geom_point(color="blue", alpha=0.5) +geom_smooth(color="darkred") + xlab ("Skewness") + ylab ("Return")
## `geom_smooth()` using method = 'gam' and formula = 'y ~ s(x, bs = "cs")'
ggplot(port.info.data, aes(x=V7, y=V1)) + geom_point(color="blue", alpha=0.5) +geom_smooth(color="darkred") + xlab ("Kurtosis") + ylab ("Return")
## `geom_smooth()` using method = 'gam' and formula = 'y ~ s(x, bs = "cs")'
ggplot(port.info.data, aes(x=V3, y=V6)) + geom_point(color="blue", alpha=0.5) +geom_smooth(color="darkred") + xlab ("Volatlity Correlation") + ylab ("Skewness")
## `geom_smooth()` using method = 'gam' and formula = 'y ~ s(x, bs = "cs")'
ggplot(port.info.data, aes(x=V3, y=V7)) + geom_point(color="blue", alpha=0.5) +geom_smooth(color="darkred") + xlab ("Volatlity Correlation") + ylab ("Kurtosis")
## `geom_smooth()` using method = 'gam' and formula = 'y ~ s(x, bs = "cs")'
ggplot(port.info.data, aes(x=V3, y=V1)) + geom_point(color="blue", alpha=0.5) +geom_smooth(color="darkred") + xlab ("Volatlity Correlation") + ylab ("Return")
## `geom_smooth()` using method = 'gam' and formula = 'y ~ s(x, bs = "cs")'
ggplot(port.info.data, aes(x=V3, y=V2)) + geom_point(color="blue", alpha=0.5) +geom_smooth(color="darkred") + xlab ("Volatlity Correlation") + ylab ("Volatility")
## `geom_smooth()` using method = 'gam' and formula = 'y ~ s(x, bs = "cs")'
ggplot(port.info.data, aes(x=V2, y=V1)) + geom_point(color="blue", alpha=0.5) +geom_smooth(color="darkred") + xlab ("Volatlity") + ylab ("Return")
## `geom_smooth()` using method = 'gam' and formula = 'y ~ s(x, bs = "cs")'
ggplot(port.info.data, aes(x=V3, y=V2)) + geom_point(color="blue", alpha=0.5) +geom_smooth(color="darkred") + xlab ("Volatlity Correlation") + ylab ("Volatlity")
## `geom_smooth()` using method = 'gam' and formula = 'y ~ s(x, bs = "cs")'
ggplot(port.info.data, aes(x=V4, y=V2)) + geom_point(color="blue", alpha=0.5) +geom_smooth(color="darkred") + xlab ("Sign Correlation") + ylab ("Volatility")
## `geom_smooth()` using method = 'gam' and formula = 'y ~ s(x, bs = "cs")'
ggplot(port.info.data, aes(x=V4, y=V6)) + geom_point(color="blue", alpha=0.5) +geom_smooth(color="darkred") + xlab ("Sign Correlation") + ylab ("Skewness")
## `geom_smooth()` using method = 'gam' and formula = 'y ~ s(x, bs = "cs")'
ggplot(port.info.data, aes(x=V4, y=V7)) + geom_point(color="blue", alpha=0.5) +geom_smooth(color="darkred") + xlab ("Sign Correlation") + ylab ("Kurtosis")
## `geom_smooth()` using method = 'gam' and formula = 'y ~ s(x, bs = "cs")'
ggplot(port.info.data, aes(x=V4, y=V1)) + geom_point(color="blue", alpha=0.5) +geom_smooth(color="darkred") + xlab ("Sign Correlation") + ylab ("Return")
## `geom_smooth()` using method = 'gam' and formula = 'y ~ s(x, bs = "cs")'
We now create a data table to store all the values together (using sd).
# Storing the values in the table (5 columns and 8000 rows)
portfolio_values1 <- tibble(Return = port_returns,
Risk1 = port_risk.var1,
Risk2 = port_risk.var2,
Risk3 = port_risk.var3,
Risk4 = port_risk.var4,
Risk5 = port_risk.mad,
SharpeRatio1 = Sharpe_ratio.sd1,
SharpeRatio2 = Sharpe_ratio.sd2,
SharpeRatio3 = Sharpe_ratio.sd3,
SharpeRatio4 = Sharpe_ratio.sd4,
SharpeRatio5 = Sharpe_ratio.mad,
)
# Converting matrix to a tibble and changing column names
all_wts1 <- tk_tbl(all_wts1)
## Warning in tk_tbl.data.frame(as.data.frame(data), preserve_index, rename_index,
## : Warning: No index to preserve. Object otherwise converted to tibble
## successfully.
colnames(all_wts1) <- colnames(asset_returns)
# Combing all the values together
portfolio_values1 <- tk_tbl(cbind(all_wts1, portfolio_values1))
## Warning in tk_tbl.data.frame(cbind(all_wts1, portfolio_values1)): Warning: No
## index to preserve. Object otherwise converted to tibble successfully.
We have the weights in each asset with the risk and returns along with the Sharpe ratio of each portfolio. We use daily data to determine the portfolios.
Next lets look at the portfolios that matter the most.
min_var1 <- portfolio_values1[which.min(portfolio_values1$Risk1),]
min_var2 <- portfolio_values1[which.min(portfolio_values1$Risk2),]
min_var3 <- portfolio_values1[which.min(portfolio_values1$Risk3),]
min_var4 <- portfolio_values1[which.min(portfolio_values1$Risk4),]
min_mad <- portfolio_values1[which.min(portfolio_values1$Risk5),]
max_sr1 <- portfolio_values1[which.max(portfolio_values1$SharpeRatio1),]
max_sr2 <- portfolio_values1[which.max(portfolio_values1$SharpeRatio2),]
max_sr3 <- portfolio_values1[which.max(portfolio_values1$SharpeRatio3),]
max_sr4 <- portfolio_values1[which.max(portfolio_values1$SharpeRatio4),]
max_sr5 <- portfolio_values1[which.max(portfolio_values1$SharpeRatio5),]
rbind(min_var1, min_var2, min_var3, min_var4, min_mad, max_sr1, max_sr2, max_sr3, max_sr4, max_sr5)
## # A tibble: 10 × 16
## ETH.USD JNJ MMM T V Return Risk1 Risk2 Risk3 Risk4
## <dbl> <dbl> <dbl> <dbl> <dbl> <dbl> <dbl> <dbl> <dbl> <dbl>
## 1 0.0315 0.350 0.0295 0.152 0.437 -7.33e-5 0.00741 0.00248 0.00461 0.00154
## 2 0.0302 0.320 0.0417 0.197 0.411 -1.35e-4 0.00751 0.00241 0.00469 0.00150
## 3 0.0510 0.347 0.0196 0.110 0.472 3.71e-5 0.00747 0.00249 0.00454 0.00151
## 4 0.0547 0.343 0.0635 0.0599 0.479 3.26e-5 0.00759 0.00245 0.00464 0.00150
## 5 0.0136 0.467 0.0402 0.112 0.367 -1.88e-4 0.00746 0.00293 0.00480 0.00189
## 6 0.211 0.0435 0.0159 0.00766 0.722 7.35e-4 0.0107 0.00383 0.00646 0.00232
## 7 0.211 0.0435 0.0159 0.00766 0.722 7.35e-4 0.0107 0.00383 0.00646 0.00232
## 8 0.211 0.0435 0.0159 0.00766 0.722 7.35e-4 0.0107 0.00383 0.00646 0.00232
## 9 0.211 0.0435 0.0159 0.00766 0.722 7.35e-4 0.0107 0.00383 0.00646 0.00232
## 10 0.498 0.0309 0.00161 0.0506 0.419 1.05e-3 0.0165 0.00808 0.0112 0.00551
## # ℹ 6 more variables: Risk5 <dbl>, SharpeRatio1 <dbl>, SharpeRatio2 <dbl>,
## # SharpeRatio3 <dbl>, SharpeRatio4 <dbl>, SharpeRatio5 <dbl>
xtable(rbind(min_var1, min_var2, min_var3, min_var4, min_mad, max_sr1, max_sr2, max_sr3, max_sr4, max_sr5), digits = 6)
## % latex table generated in R 4.3.1 by xtable 1.8-4 package
## % Tue Sep 24 19:03:15 2024
## \begin{table}[ht]
## \centering
## \begin{tabular}{rrrrrrrrrrrrrrrrr}
## \hline
## & ETH.USD & JNJ & MMM & T & V & Return & Risk1 & Risk2 & Risk3 & Risk4 & Risk5 & SharpeRatio1 & SharpeRatio2 & SharpeRatio3 & SharpeRatio4 & SharpeRatio5 \\
## \hline
## 1 & 0.031506 & 0.349599 & 0.029541 & 0.152226 & 0.437128 & -0.000073 & 0.007412 & 0.002480 & 0.004613 & 0.001543 & 0.005772 & -0.009884 & -0.029546 & -0.015880 & -0.047469 & -0.012693 \\
## 2 & 0.030201 & 0.319992 & 0.041704 & 0.196931 & 0.411171 & -0.000135 & 0.007515 & 0.002411 & 0.004688 & 0.001504 & 0.005829 & -0.017966 & -0.056000 & -0.028797 & -0.089763 & -0.023160 \\
## 3 & 0.050986 & 0.347152 & 0.019610 & 0.110396 & 0.471857 & 0.000037 & 0.007469 & 0.002486 & 0.004536 & 0.001510 & 0.005881 & 0.004974 & 0.014942 & 0.008189 & 0.024601 & 0.006317 \\
## 4 & 0.054743 & 0.343166 & 0.063531 & 0.059921 & 0.478639 & 0.000033 & 0.007588 & 0.002450 & 0.004643 & 0.001499 & 0.005978 & 0.004303 & 0.013325 & 0.007032 & 0.021777 & 0.005462 \\
## 5 & 0.013640 & 0.467064 & 0.040199 & 0.112254 & 0.366844 & -0.000188 & 0.007458 & 0.002933 & 0.004796 & 0.001886 & 0.005683 & -0.025143 & -0.063936 & -0.039103 & -0.099435 & -0.032997 \\
## 6 & 0.211466 & 0.043482 & 0.015853 & 0.007661 & 0.721537 & 0.000735 & 0.010657 & 0.003831 & 0.006461 & 0.002323 & 0.008474 & 0.068923 & 0.191742 & 0.113679 & 0.316251 & 0.086680 \\
## 7 & 0.211466 & 0.043482 & 0.015853 & 0.007661 & 0.721537 & 0.000735 & 0.010657 & 0.003831 & 0.006461 & 0.002323 & 0.008474 & 0.068923 & 0.191742 & 0.113679 & 0.316251 & 0.086680 \\
## 8 & 0.211466 & 0.043482 & 0.015853 & 0.007661 & 0.721537 & 0.000735 & 0.010657 & 0.003831 & 0.006461 & 0.002323 & 0.008474 & 0.068923 & 0.191742 & 0.113679 & 0.316251 & 0.086680 \\
## 9 & 0.211466 & 0.043482 & 0.015853 & 0.007661 & 0.721537 & 0.000735 & 0.010657 & 0.003831 & 0.006461 & 0.002323 & 0.008474 & 0.068923 & 0.191742 & 0.113679 & 0.316251 & 0.086680 \\
## 10 & 0.497908 & 0.030887 & 0.001608 & 0.050640 & 0.418958 & 0.001053 & 0.016468 & 0.008085 & 0.011218 & 0.005507 & 0.012018 & 0.063924 & 0.130207 & 0.093840 & 0.191144 & 0.087592 \\
## \hline
## \end{tabular}
## \end{table}
# change min_var1[1:nassets] and all the indexes after that accordingly
p1 <- cbind(min_var1[1:nasset], 252*min_var1[nasset+1], sqrt(252)*min_var1[nasset+2], sqrt(252)*min_var1[nasset+7])
p2 <- cbind(min_var2[1:nasset], 252*min_var2[nasset+1], sqrt(252)*min_var2[nasset+3], sqrt(252)*min_var2[nasset+8])
p3 <- cbind(min_var3[1:nasset], 252*min_var3[nasset+1], sqrt(252)*min_var3[nasset+4], sqrt(252)*min_var3[nasset+9])
p4 <- cbind(min_var4[1:nasset], 252*min_var4[nasset+1], sqrt(252)*min_var4[nasset+5], sqrt(252)*min_var4[nasset+10])
p5 <- cbind(min_mad[1:nasset], 252*min_mad[nasset+1], sqrt(252)*min_mad[nasset+6], sqrt(252)*min_mad[nasset+11])
xtable(t(rbind(as.numeric(p1), as.numeric(p2), as.numeric(p3), as.numeric(p4), as.numeric(p5))), digits = 5)
## % latex table generated in R 4.3.1 by xtable 1.8-4 package
## % Tue Sep 24 19:03:15 2024
## \begin{table}[ht]
## \centering
## \begin{tabular}{rrrrrr}
## \hline
## & 1 & 2 & 3 & 4 & 5 \\
## \hline
## 1 & 0.03151 & 0.03020 & 0.05099 & 0.05474 & 0.01364 \\
## 2 & 0.34960 & 0.31999 & 0.34715 & 0.34317 & 0.46706 \\
## 3 & 0.02954 & 0.04170 & 0.01961 & 0.06353 & 0.04020 \\
## 4 & 0.15223 & 0.19693 & 0.11040 & 0.05992 & 0.11225 \\
## 5 & 0.43713 & 0.41117 & 0.47186 & 0.47864 & 0.36684 \\
## 6 & -0.01846 & -0.03402 & 0.00936 & 0.00823 & -0.04726 \\
## 7 & 0.11766 & 0.03827 & 0.07201 & 0.02380 & 0.09022 \\
## 8 & -0.15691 & -0.88898 & 0.13000 & 0.34570 & -0.52380 \\
## \hline
## \end{tabular}
## \end{table}
# change max_sr[1:nassets] and all the indexes after that accordingly
p1 <- cbind(max_sr1[1:nasset], 252*max_sr1[nasset+1], sqrt(252)*max_sr1[nasset+2], sqrt(252)*max_sr1[nasset+7])
p2 <- cbind(max_sr2[1:nasset], 252*max_sr2[nasset+1], sqrt(252)*max_sr2[nasset+3], sqrt(252)*max_sr2[nasset+8])
p3 <- cbind(max_sr3[1:nasset], 252*max_sr3[nasset+1], sqrt(252)*max_sr3[nasset+4], sqrt(252)*max_sr3[nasset+9])
p4 <- cbind(max_sr4[1:nasset], 252*max_sr4[nasset+1], sqrt(252)*max_sr4[nasset+5], sqrt(252)*max_sr4[nasset+10])
p5 <- cbind(max_sr5[1:nasset], 252*max_sr5[nasset+1], sqrt(252)*max_sr5[nasset+6], sqrt(252)*max_sr5[nasset+11])
xtable(t(rbind(as.numeric(p1), as.numeric(p2), as.numeric(p3), as.numeric(p4), as.numeric(p5))), digits = 5)
## % latex table generated in R 4.3.1 by xtable 1.8-4 package
## % Tue Sep 24 19:03:15 2024
## \begin{table}[ht]
## \centering
## \begin{tabular}{rrrrrr}
## \hline
## & 1 & 2 & 3 & 4 & 5 \\
## \hline
## 1 & 0.21147 & 0.21147 & 0.21147 & 0.21147 & 0.49791 \\
## 2 & 0.04348 & 0.04348 & 0.04348 & 0.04348 & 0.03089 \\
## 3 & 0.01585 & 0.01585 & 0.01585 & 0.01585 & 0.00161 \\
## 4 & 0.00766 & 0.00766 & 0.00766 & 0.00766 & 0.05064 \\
## 5 & 0.72154 & 0.72154 & 0.72154 & 0.72154 & 0.41896 \\
## 6 & 0.18510 & 0.18510 & 0.18510 & 0.18510 & 0.26527 \\
## 7 & 0.16918 & 0.06081 & 0.10257 & 0.03687 & 0.19078 \\
## 8 & 1.09412 & 3.04381 & 1.80459 & 5.02033 & 1.39048 \\
## \hline
## \end{tabular}
## \end{table}
nasset <- ncol(asset_returns)
w1 <- min_var1[, 1:nasset] %>% gather () %>% arrange(desc(value))
w2 <- min_var2[, 1:nasset] %>% gather () %>% arrange(desc(value))
w3 <- min_var3[, 1:nasset] %>% gather () %>% arrange(desc(value))
w4 <- min_var4[, 1:nasset] %>% gather () %>% arrange(desc(value))
w5 <- min_mad[, 1:nasset] %>% gather () %>% arrange(desc(value))
w6 <- max_sr1[, 1:nasset] %>% gather () %>% arrange(desc(value))
w7 <- max_sr2[, 1:nasset] %>% gather () %>% arrange(desc(value))
w8 <- max_sr3[, 1:nasset] %>% gather () %>% arrange(desc(value))
w9 <- max_sr4[, 1:nasset] %>% gather () %>% arrange(desc(value))
w10 <- max_sr5[, 1:nasset] %>% gather () %>% arrange(desc(value))
xtable(cbind(head (w1, 10), head (w2, 10), head (w3, 10), head (w4, 10), head (w5, 10), head (w6, 10), head (w7, 10), head (w8, 10), head (w9, 10), head (w10, 10)), digits = 4)
## % latex table generated in R 4.3.1 by xtable 1.8-4 package
## % Tue Sep 24 19:03:15 2024
## \begin{table}[ht]
## \centering
## \begin{tabular}{rlrlrlrlrlrlrlrlrlrlr}
## \hline
## & key & value & key & value & key & value & key & value & key & value & key & value & key & value & key & value & key & value & key & value \\
## \hline
## 1 & V & 0.4371 & V & 0.4112 & V & 0.4719 & V & 0.4786 & JNJ & 0.4671 & V & 0.7215 & V & 0.7215 & V & 0.7215 & V & 0.7215 & ETH.USD & 0.4979 \\
## 2 & JNJ & 0.3496 & JNJ & 0.3200 & JNJ & 0.3472 & JNJ & 0.3432 & V & 0.3668 & ETH.USD & 0.2115 & ETH.USD & 0.2115 & ETH.USD & 0.2115 & ETH.USD & 0.2115 & V & 0.4190 \\
## 3 & T & 0.1522 & T & 0.1969 & T & 0.1104 & MMM & 0.0635 & T & 0.1123 & JNJ & 0.0435 & JNJ & 0.0435 & JNJ & 0.0435 & JNJ & 0.0435 & T & 0.0506 \\
## 4 & ETH.USD & 0.0315 & MMM & 0.0417 & ETH.USD & 0.0510 & T & 0.0599 & MMM & 0.0402 & MMM & 0.0159 & MMM & 0.0159 & MMM & 0.0159 & MMM & 0.0159 & JNJ & 0.0309 \\
## 5 & MMM & 0.0295 & ETH.USD & 0.0302 & MMM & 0.0196 & ETH.USD & 0.0547 & ETH.USD & 0.0136 & T & 0.0077 & T & 0.0077 & T & 0.0077 & T & 0.0077 & MMM & 0.0016 \\
## \hline
## \end{tabular}
## \end{table}
Lets plot the weights of each portfolio. First with the minimum variance portfolio.
p1 <- min_var4 %>%
gather(colnames(asset_returns)[1]:colnames(asset_returns)[nasset], key = Asset,
value = Weights) %>%
mutate(Asset = as.factor(Asset)) %>%
ggplot(aes(x = fct_reorder(Asset,Weights), y = Weights, fill = Asset)) +
geom_bar(stat = 'identity') +
theme_minimal() +
labs(x = 'Assets', y = 'Weights', title = "Minimum Risk Portfolio Weights") +
scale_y_continuous(labels = scales::percent)
ggplotly(p1)
p2 <- max_sr4 %>%
gather(colnames(asset_returns)[1]:colnames(asset_returns)[nasset], key = Asset,
value = Weights) %>%
mutate(Asset = as.factor(Asset)) %>%
ggplot(aes(x = fct_reorder(Asset, Weights), y = Weights, fill = Asset)) +
geom_bar(stat = 'identity') +
theme_minimal() +
labs(x = 'Assets', y = 'Weights', title = "Tangency Portfolio Weights") +
scale_y_continuous(labels = scales::percent)
ggplotly(p2)
#convert daily return, risk, SR to annualized ones
portfolio_values1_annual <- portfolio_values1 %>% mutate(Return = Return * 252) %>% mutate(Risk1 = Risk1 * sqrt(252), Risk2 = Risk2 * sqrt(252), Risk3 = Risk3 * sqrt(252), Risk4 = Risk4 * sqrt(252), Risk5 = Risk5 * sqrt(252)) %>% mutate(SharpeRatio1 = SharpeRatio1 * sqrt(252), SharpeRatio2 = SharpeRatio2 * sqrt(252), SharpeRatio3 = SharpeRatio3 * sqrt(252), SharpeRatio4 = SharpeRatio4 * sqrt(252), SharpeRatio5 = SharpeRatio5 * sqrt(252))
min_var1.a <- portfolio_values1_annual[which.min(portfolio_values1_annual$Risk1),]
min_var2.a <- portfolio_values1_annual[which.min(portfolio_values1_annual$Risk2),]
min_var3.a <- portfolio_values1_annual[which.min(portfolio_values1_annual$Risk3),]
min_var4.a <- portfolio_values1_annual[which.min(portfolio_values1_annual$Risk4),]
min_mad.a <- portfolio_values1_annual[which.min(portfolio_values1_annual$Risk5),]
max_sr1.a <- portfolio_values1_annual[which.max(portfolio_values1_annual$SharpeRatio1),]
max_sr2.a <- portfolio_values1_annual[which.max(portfolio_values1_annual$SharpeRatio2),]
max_sr3.a <- portfolio_values1_annual[which.max(portfolio_values1_annual$SharpeRatio3),]
max_sr4.a <- portfolio_values1_annual[which.max(portfolio_values1_annual$SharpeRatio4),]
max_sr5.a <- portfolio_values1_annual[which.max(portfolio_values1_annual$SharpeRatio5),]
rbind(min_var1.a, min_var2.a, min_var3.a, min_var4.a, min_mad.a, max_sr1.a, max_sr2.a, max_sr3.a, max_sr4.a, max_sr5.a)
## # A tibble: 10 × 16
## ETH.USD JNJ MMM T V Return Risk1 Risk2 Risk3 Risk4
## <dbl> <dbl> <dbl> <dbl> <dbl> <dbl> <dbl> <dbl> <dbl> <dbl>
## 1 0.0315 0.350 0.0295 0.152 0.437 -0.0185 0.118 0.0394 0.0732 0.0245
## 2 0.0302 0.320 0.0417 0.197 0.411 -0.0340 0.119 0.0383 0.0744 0.0239
## 3 0.0510 0.347 0.0196 0.110 0.472 0.00936 0.119 0.0395 0.0720 0.0240
## 4 0.0547 0.343 0.0635 0.0599 0.479 0.00823 0.120 0.0389 0.0737 0.0238
## 5 0.0136 0.467 0.0402 0.112 0.367 -0.0473 0.118 0.0466 0.0761 0.0299
## 6 0.211 0.0435 0.0159 0.00766 0.722 0.185 0.169 0.0608 0.103 0.0369
## 7 0.211 0.0435 0.0159 0.00766 0.722 0.185 0.169 0.0608 0.103 0.0369
## 8 0.211 0.0435 0.0159 0.00766 0.722 0.185 0.169 0.0608 0.103 0.0369
## 9 0.211 0.0435 0.0159 0.00766 0.722 0.185 0.169 0.0608 0.103 0.0369
## 10 0.498 0.0309 0.00161 0.0506 0.419 0.265 0.261 0.128 0.178 0.0874
## # ℹ 6 more variables: Risk5 <dbl>, SharpeRatio1 <dbl>, SharpeRatio2 <dbl>,
## # SharpeRatio3 <dbl>, SharpeRatio4 <dbl>, SharpeRatio5 <dbl>
p1 <- portfolio_values1_annual %>%
ggplot(aes(x = Risk1, y = Return, color = SharpeRatio1)) +
geom_point(alpha = 0.4)+
theme_classic() +
scale_y_continuous(labels = scales::percent) +
scale_x_continuous(labels = scales::percent) +
labs(x = 'Annualized Risk (SD)',
y = 'Annualized Returns',
title = "Portfolio Optimization & Efficient Frontier") +
geom_point(aes(x = Risk1,
y = Return), data = min_var1.a, color = 'orange') +
geom_point(aes(x = Risk1,
y = Return), data = max_sr1.a, color = 'orange4', shape = 18)
ggplotly(p1)
p2 <- portfolio_values1_annual %>%
ggplot(aes(x = Risk2, y = Return, color = SharpeRatio2)) +
geom_point(alpha = 0.4)+
theme_classic() +
scale_y_continuous(labels = scales::percent) +
scale_x_continuous(labels = scales::percent) +
labs(x = 'Annualized Risk (VEV)',
y = 'Annualized Returns',
title = "Portfolio Optimization & Efficient Frontier") +
geom_point(aes(x = Risk2,
y = Return), data = min_var2.a, color = 'green') +
geom_point(aes(x = Risk2,
y = Return), data = max_sr2.a, color = 'green4', shape = 18)
ggplotly(p2)
p3 <- portfolio_values1_annual %>%
ggplot(aes(x = Risk3, y = Return, color = SharpeRatio3)) +
geom_point(alpha = 0.4)+
theme_classic() +
scale_y_continuous(labels = scales::percent) +
scale_x_continuous(labels = scales::percent) +
labs(x = 'Annualized Risk (VES)',
y = 'Annualized Returns',
title = "Portfolio Optimization & Efficient Frontier") +
geom_point(aes(x = Risk3,
y = Return), data = min_var3.a, color = 'red') +
geom_point(aes(x = Risk3,
y = Return), data = max_sr3.a, color = 'red4', shape = 18)
ggplotly(p3)
p4 <- portfolio_values1_annual %>%
ggplot(aes(x = Risk4, y = Return, color = SharpeRatio4)) +
geom_point(alpha = 0.4)+
theme_classic() +
scale_y_continuous(labels = scales::percent) +
scale_x_continuous(labels = scales::percent) +
labs(x = 'Annualized Risk (VESV)',
y = 'Annualized Returns',
title = "Portfolio Optimization & Efficient Frontier") +
geom_point(aes(x = Risk4,
y = Return), data = min_var4.a, color = 'purple') +
geom_point(aes(x = Risk4,
y = Return), data = max_sr4.a, color = 'purple4', shape = 18)
ggplotly(p4)
p5 <- portfolio_values1_annual %>%
ggplot(aes(x = Risk5, y = Return, color = SharpeRatio5)) +
geom_point(alpha = 0.4)+
theme_classic() +
scale_y_continuous(labels = scales::percent) +
scale_x_continuous(labels = scales::percent) +
labs(x = 'Annualized Risk (MAD)',
y = 'Annualized Returns',
title = "Portfolio Optimization & Efficient Frontier") +
geom_point(aes(x = Risk5,
y = Return), data = min_mad.a, color = 'blue') +
geom_point(aes(x = Risk5,
y = Return), data = max_sr5.a, color = 'blue4', shape = 18)
ggplotly(p5)
MVP1 <- as.matrix(test)%*%as.vector(as.numeric(min_var1[1:nasset]))
MVP2 <- as.matrix(test)%*%as.vector(as.numeric(min_var2[1:nasset]))
MVP3 <- as.matrix(test)%*%as.vector(as.numeric(min_var3[1:nasset]))
MVP4 <- as.matrix(test)%*%as.vector(as.numeric(min_var4[1:nasset]))
MVP5 <- as.matrix(test)%*%as.vector(as.numeric(min_mad[1:nasset]))
TP1<-as.matrix(test)%*%as.vector(as.numeric(max_sr1[1:nasset]))
TP2<-as.matrix(test)%*%as.vector(as.numeric(max_sr2[1:nasset]))
TP3<-as.matrix(test)%*%as.vector(as.numeric(max_sr3[1:nasset]))
TP4<-as.matrix(test)%*%as.vector(as.numeric(max_sr4[1:nasset]))
TP5<-as.matrix(test)%*%as.vector(as.numeric(max_sr5[1:nasset]))
EWQ<-as.matrix(test)%*%as.vector(rep(1/nasset, nasset))
assets <- c("MVP1", "MVP2", "MVP3", "MVP4", "MVP5", "TP1", "TP2", "TP3", "TP4", "TP5", "EWQ")
#Portfolios <- merge(test[, 1], cumsum(MVP1), cumsum(MVP2), cumsum(MVP3), cumsum(MVP4), cumsum(MVP5), cumsum(TP1), cumsum(TP2), cumsum(TP3), cumsum(TP4), cumsum(TP5), cumsum(EWQ))[, -c(1)]
Portfolios <- cbind.data.frame(cumsum(MVP1), cumsum(MVP2), cumsum(MVP3), cumsum(MVP4), cumsum(MVP5), cumsum(TP1), cumsum(TP2), cumsum(TP3), cumsum(TP4), cumsum(TP5), cumsum(EWQ))
colnames(Portfolios) <- assets
# Define start and end dates
start_date <- as.Date("2023-01-01")
end_date <- as.Date("2023-12-31")
# Create a sequence of dates
date_sequence <- seq(start_date, end_date, by = "day")
#date_sequence
# Number of last values to select
nTemp <- nrow(Portfolios)
# Select the last 'n' values from the vector
TestDates <- date_sequence[(length(date_sequence) - nTemp + 1):length(date_sequence)]
#TestDates
row.names(Portfolios) <- TestDates
dygraph(Portfolios, main = 'Cummulative Returns for Test Period')%>%
dySeries('MVP1', label = 'MVP', col = "orange") %>%
dySeries('MVP2', label = 'MRP2', col = "green") %>%
dySeries('MVP3', label = 'MRP3', col = "red") %>%
dySeries('MVP4', label = 'MRP4', col = "purple") %>%
dySeries('MVP5', label = 'MRP5', col = "blue") %>%
dySeries('TP1', label = 'TP', col = "orange", drawPoints = TRUE) %>%
dySeries('TP2', label = 'MRRP2', col = "green", drawPoints = TRUE) %>%
dySeries('TP3', label = 'MRRP3', col = "red", drawPoints = TRUE) %>%
dySeries('TP4', label = 'MRRP4', col = "purple", drawPoints = TRUE) %>%
dySeries('TP5', label = 'MRRP5', col = "blue", drawPoints = TRUE) %>%
dySeries('EWQ', label = 'EWQ', col = "black") %>%
dyRangeSelector(height = 30)%>%
dyLegend(width = 500)
CumReturnVolCorr_low_avg_risk <- cumsum(TP2)
CumReturnVolCorr_low_avg_risk
## [1] 0.0095167234 -0.0002951153 0.0050872055 0.0013452655 0.0007513137
## [6] 0.0052135808 0.0195404998 0.0181003257 0.0052649781 -0.0052085142
## [11] -0.0013540487 0.0132600908 0.0263540357 0.0332713796 0.0173680036
## [16] 0.0069384368 0.0235148152 0.0312231910 0.0455937311 0.0552304587
## [21] 0.0607049293 0.0680976089 0.0703386913 0.0690768171 0.0872798825
## [26] 0.0939906138 0.0900038265 0.0892799249 0.1020998455 0.0937259832
## [31] 0.0965013138 0.1046790798 0.1025245915 0.1208274128 0.1247899676
## [36] 0.1187131481 0.1179142026 0.1197793875 0.1300424200 0.1342173959
## [41] 0.1450370326 0.1501906440 0.1430690426 0.1591467407 0.1586878642
## [46] 0.1488734764 0.1550955878 0.1690356703 0.1650585009 0.1536869919
## [51] 0.1543271792 0.1555056965 0.1484786037 0.1596885582 0.1651334557
## [56] 0.1589962204 0.1724679030 0.1740693608 0.1697175983
#Import data
mi_DBSCAN_2023_lowest_risk <- read.csv("~/Desktop/PO/DBSCAN/MI/2023/mi_DBSCAN_2023_lowest_risk.csv")
#remove the date column
asset_prices<-mi_DBSCAN_2023_lowest_risk[,-1]
# calculate returns
ret_tidy1 = apply(asset_prices,2, log)
head(ret_tidy1)
## KO PEP PG V WMT
## [1,] 4.088750 5.138329 4.977250 5.320976 3.843580
## [2,] 4.088274 5.135873 4.981595 5.345835 3.844693
## [3,] 4.076765 5.125369 4.969101 5.338754 3.841279
## [4,] 4.095873 5.147704 4.992635 5.369723 3.865483
## [5,] 4.083335 5.137882 4.980346 5.373619 3.852937
## [6,] 4.075639 5.129595 4.979359 5.384945 3.852316
ret_tidy2 = diff(ret_tidy1)
head(ret_tidy2)
## KO PEP PG V WMT
## [1,] -0.0004768126 -0.002455618 0.0043448416 0.024858388 0.0011135033
## [2,] -0.0115088793 -0.010503589 -0.0124932247 -0.007080126 -0.0034141655
## [3,] 0.0191087017 0.022334741 0.0235337106 0.030968202 0.0242037550
## [4,] -0.0125388092 -0.009821675 -0.0122893509 0.003895977 -0.0125459523
## [5,] -0.0076960201 -0.008287110 -0.0009870545 0.011326329 -0.0006209848
## [6,] -0.0019333764 0.001123804 -0.0081309353 0.004557829 0.0087289003
ret_tidy = exp (ret_tidy2) - 1 #simple returns
#remove first row
asset_returns <- ret_tidy[-1,]
#no.of assets in the portfolio
nasset<-ncol(asset_returns)
# testing and training data sets (each data set has 252 observations)
# Divide the data set in to 3:1 (75% training and 25% testing)
# testing period - January - September (189 data points)
# training period - October - December (62 data points)
n.total<-252
n.train<- 189
train = asset_returns[1:n.train,]
test = asset_returns[-(1:(n.train)),]
##summary statistics
rhosign<-apply(as.matrix(train), MARGIN=2, FUN=rho.cal)
rhovol<-apply(as.matrix(train), MARGIN=2, FUN=rho.vol)
assetsummary<-data.frame(apply(train, 2, mean), apply(train, 2, sd), rhovol, rhosign, apply(train, 2, skewness),
apply(train, 2, kurtosis))
xtable(assetsummary, digits=4)
## % latex table generated in R 4.3.1 by xtable 1.8-4 package
## % Tue Sep 24 19:03:20 2024
## \begin{table}[ht]
## \centering
## \begin{tabular}{rrrrrrr}
## \hline
## & apply.train..2..mean. & apply.train..2..sd. & rhovol & rhosign & apply.train..2..skewness. & apply.train..2..kurtosis. \\
## \hline
## KO & -0.0008 & 0.0084 & 0.8623 & 0.7384 & -0.9780 & 5.1824 \\
## PEP & -0.0004 & 0.0095 & 0.8571 & 0.7284 & -0.7361 & 4.0926 \\
## PG & -0.0002 & 0.0092 & 0.9194 & 0.7529 & 0.2519 & 1.2707 \\
## V & 0.0006 & 0.0101 & 0.9360 & 0.7797 & 0.2072 & 0.6578 \\
## WMT & 0.0006 & 0.0084 & 0.9356 & 0.7931 & -0.2408 & 0.2941 \\
## \hline
## \end{tabular}
## \end{table}
plot(train, legend.loc=1)
## Warning in plot.window(...): "legend.loc" is not a graphical parameter
## Warning in plot.xy(xy, type, ...): "legend.loc" is not a graphical parameter
## Warning in axis(side = side, at = at, labels = labels, ...): "legend.loc" is
## not a graphical parameter
## Warning in axis(side = side, at = at, labels = labels, ...): "legend.loc" is
## not a graphical parameter
## Warning in box(...): "legend.loc" is not a graphical parameter
## Warning in title(...): "legend.loc" is not a graphical parameter
Lets calculate annualized portfolio return, risk, and gamma from the simulated portfolio returns with portfolio weights. (simulated weights)
## portfolio return, sd and gamma
## w is the random weight
## data = train or test
portfolio_info = function(w, data){
port.data <- data%*%as.vector(w)
port.cdf <- ecdf(port.data)
port.return <- mean (port.data)
port.sd <- sd (port.data)
port.signrho <- cor (port.data - port.return, sign(port.data - port.return))
# port.signrho3 <- cor (sign(port.data - port.return), (port.data - port.return)^3)
# port.skewrho <- cor (port.data - port.return, (port.data - port.return)^2)
port.volcor <- cor (abs(port.data - port.return), (port.data - port.return)^2) #volatlity correlation
port.skewness <- skewness (port.data) #mu_3/sigma^3
port.kurtosis <- kurtosis (port.data) #excess kurtosis mu_4/sigma^4 - 3
return(c(port.return, port.sd, port.volcor, port.signrho, port.cdf(port.return), port.skewness, port.kurtosis))
}
# In stat matrix and weight matrix nrow = no.of assets in the portfolio (need to change), ncol is fixed to 7 , for loop i in 1:nrow
stat<-matrix(0, nrow = nasset, ncol = 7)
weight<-matrix(0, nrow = nasset, ncol = nasset)
for (i in 1:nasset){
weight[i, ] <- get_weights(nasset)
stat[i, ] <- portfolio_info (weight[i, ], as.matrix(train))
}
xtable(weight, digits = 4)
## % latex table generated in R 4.3.1 by xtable 1.8-4 package
## % Tue Sep 24 19:03:21 2024
## \begin{table}[ht]
## \centering
## \begin{tabular}{rrrrrr}
## \hline
## & 1 & 2 & 3 & 4 & 5 \\
## \hline
## 1 & 0.0254 & 0.1453 & 0.3117 & 0.1860 & 0.3316 \\
## 2 & 0.1804 & 0.2324 & 0.1471 & 0.3566 & 0.0835 \\
## 3 & 0.0865 & 0.2469 & 0.3411 & 0.0842 & 0.2412 \\
## 4 & 0.3280 & 0.0446 & 0.3116 & 0.3155 & 0.0003 \\
## 5 & 0.2309 & 0.1093 & 0.0727 & 0.3527 & 0.2344 \\
## \hline
## \end{tabular}
## \end{table}
xtable(stat, digits = 4)
## % latex table generated in R 4.3.1 by xtable 1.8-4 package
## % Tue Sep 24 19:03:21 2024
## \begin{table}[ht]
## \centering
## \begin{tabular}{rrrrrrrr}
## \hline
## & 1 & 2 & 3 & 4 & 5 & 6 & 7 \\
## \hline
## 1 & 0.0002 & 0.0068 & 0.9117 & 0.7641 & 0.5079 & -0.1264 & 1.0383 \\
## 2 & -0.0000 & 0.0068 & 0.9122 & 0.7733 & 0.4974 & -0.1687 & 1.0569 \\
## 3 & -0.0000 & 0.0072 & 0.9170 & 0.7616 & 0.5344 & -0.2412 & 1.2306 \\
## 4 & -0.0002 & 0.0069 & 0.9145 & 0.7677 & 0.5026 & -0.1327 & 0.9889 \\
## 5 & 0.0001 & 0.0066 & 0.9106 & 0.7774 & 0.4815 & -0.1277 & 1.0784 \\
## \hline
## \end{tabular}
## \end{table}
Check for the portfolio sd can be calcualted by both the formula and sd of the simulated portfolio.
We have everything we need to perform our optimization. All we need now is to run this code on 8000 random portfolios. For that we will use a for loop.
Before we do that, we need to create empty vectors and matrix for storing our values.
#change nasset to no of assets in portfolio
num_port <- 10000
nasset <- nasset
# Creating a matrix to store the weights
all_wts1 <- matrix(nrow = num_port,
ncol = nasset)
# Creating an empty vector to store
# 8000 Portfolio returns
port_returns <- vector('numeric', length = num_port)
# Creating an empty vector to store
# 8000 Portfolio variances
port_risk.var1 <- vector('numeric', length = num_port)
port_risk.var2 <- vector('numeric', length = num_port)
port_risk.var3 <- vector('numeric', length = num_port)
port_risk.var4 <- vector('numeric', length = num_port)
port_risk.mad <- vector('numeric', length = num_port)
Sharpe_ratio.sd1 <- vector('numeric', length = num_port)
Sharpe_ratio.sd2 <- vector('numeric', length = num_port)
Sharpe_ratio.sd3 <- vector('numeric', length = num_port)
Sharpe_ratio.sd4 <- vector('numeric', length = num_port)
Sharpe_ratio.mad <- vector('numeric', length = num_port)
Next lets run the for loop 10000 times.
port.info <- matrix(0, nrow = 10000, ncol = 7)
ptm <- proc.time()
for (i in seq_along(port_returns)) {
wts <- get_weights(nasset)
# Storing weight in the matrix
all_wts1[i,] <- wts
# Portfolio returns
port.info [i, ]<- portfolio_info (wts, as.matrix(train))
# Storing Portfolio Returns values
port_returns[i] <- port.info[i, 1]
# Creating and storing portfolio risk
port_risk.var1 [i] <- port.info[i, 2]
port_risk.var2 [i] <- sqrt(1 - port.info[i, 3]^2)*port.info[i, 2]
port_risk.var3 [i] <- sqrt(1 - port.info[i, 4]^2)*port.info[i, 2]
port_risk.var4 [i] <- sqrt(1 - port.info[i, 3]^2)*sqrt(1 - port.info[i, 4]^2)*port.info[i, 2]
port_risk.mad [i] <- 2*port.info[i, 2]*port.info[i, 4]*sqrt(port.info[i, 5]*(1-port.info[i, 5]))
# Creating and storing Portfolio Sharpe Ratios
# Assuming 0% Risk free rate
Sharpe_ratio.sd1 [i] <- port_returns[i]/port_risk.var1 [i]
Sharpe_ratio.sd2 [i] <- port_returns[i]/port_risk.var2 [i]
Sharpe_ratio.sd3 [i] <- port_returns[i]/port_risk.var3 [i]
Sharpe_ratio.sd4 [i] <- port_returns[i]/port_risk.var4 [i]
Sharpe_ratio.mad [i] <- port_returns[i]/port_risk.mad [i]
}
proc.time()-ptm
## user system elapsed
## 9.483 0.138 10.209
port.info.data <- as.data.frame(port.info)
ggplot(port.info.data, aes(x=V6, y=V1)) + geom_point(color="blue", alpha=0.5) +geom_smooth(color="darkred") + xlab ("Skewness") + ylab ("Return")
## `geom_smooth()` using method = 'gam' and formula = 'y ~ s(x, bs = "cs")'
ggplot(port.info.data, aes(x=V7, y=V1)) + geom_point(color="blue", alpha=0.5) +geom_smooth(color="darkred") + xlab ("Kurtosis") + ylab ("Return")
## `geom_smooth()` using method = 'gam' and formula = 'y ~ s(x, bs = "cs")'
ggplot(port.info.data, aes(x=V3, y=V6)) + geom_point(color="blue", alpha=0.5) +geom_smooth(color="darkred") + xlab ("Volatlity Correlation") + ylab ("Skewness")
## `geom_smooth()` using method = 'gam' and formula = 'y ~ s(x, bs = "cs")'
ggplot(port.info.data, aes(x=V3, y=V7)) + geom_point(color="blue", alpha=0.5) +geom_smooth(color="darkred") + xlab ("Volatlity Correlation") + ylab ("Kurtosis")
## `geom_smooth()` using method = 'gam' and formula = 'y ~ s(x, bs = "cs")'
ggplot(port.info.data, aes(x=V3, y=V1)) + geom_point(color="blue", alpha=0.5) +geom_smooth(color="darkred") + xlab ("Volatlity Correlation") + ylab ("Return")
## `geom_smooth()` using method = 'gam' and formula = 'y ~ s(x, bs = "cs")'
ggplot(port.info.data, aes(x=V3, y=V2)) + geom_point(color="blue", alpha=0.5) +geom_smooth(color="darkred") + xlab ("Volatlity Correlation") + ylab ("Volatility")
## `geom_smooth()` using method = 'gam' and formula = 'y ~ s(x, bs = "cs")'
ggplot(port.info.data, aes(x=V2, y=V1)) + geom_point(color="blue", alpha=0.5) +geom_smooth(color="darkred") + xlab ("Volatlity") + ylab ("Return")
## `geom_smooth()` using method = 'gam' and formula = 'y ~ s(x, bs = "cs")'
ggplot(port.info.data, aes(x=V3, y=V2)) + geom_point(color="blue", alpha=0.5) +geom_smooth(color="darkred") + xlab ("Volatlity Correlation") + ylab ("Volatlity")
## `geom_smooth()` using method = 'gam' and formula = 'y ~ s(x, bs = "cs")'
ggplot(port.info.data, aes(x=V4, y=V2)) + geom_point(color="blue", alpha=0.5) +geom_smooth(color="darkred") + xlab ("Sign Correlation") + ylab ("Volatility")
## `geom_smooth()` using method = 'gam' and formula = 'y ~ s(x, bs = "cs")'
ggplot(port.info.data, aes(x=V4, y=V6)) + geom_point(color="blue", alpha=0.5) +geom_smooth(color="darkred") + xlab ("Sign Correlation") + ylab ("Skewness")
## `geom_smooth()` using method = 'gam' and formula = 'y ~ s(x, bs = "cs")'
ggplot(port.info.data, aes(x=V4, y=V7)) + geom_point(color="blue", alpha=0.5) +geom_smooth(color="darkred") + xlab ("Sign Correlation") + ylab ("Kurtosis")
## `geom_smooth()` using method = 'gam' and formula = 'y ~ s(x, bs = "cs")'
ggplot(port.info.data, aes(x=V4, y=V1)) + geom_point(color="blue", alpha=0.5) +geom_smooth(color="darkred") + xlab ("Sign Correlation") + ylab ("Return")
## `geom_smooth()` using method = 'gam' and formula = 'y ~ s(x, bs = "cs")'
We now create a data table to store all the values together (using sd).
# Storing the values in the table (5 columns and 8000 rows)
portfolio_values1 <- tibble(Return = port_returns,
Risk1 = port_risk.var1,
Risk2 = port_risk.var2,
Risk3 = port_risk.var3,
Risk4 = port_risk.var4,
Risk5 = port_risk.mad,
SharpeRatio1 = Sharpe_ratio.sd1,
SharpeRatio2 = Sharpe_ratio.sd2,
SharpeRatio3 = Sharpe_ratio.sd3,
SharpeRatio4 = Sharpe_ratio.sd4,
SharpeRatio5 = Sharpe_ratio.mad,
)
# Converting matrix to a tibble and changing column names
all_wts1 <- tk_tbl(all_wts1)
## Warning in tk_tbl.data.frame(as.data.frame(data), preserve_index, rename_index,
## : Warning: No index to preserve. Object otherwise converted to tibble
## successfully.
colnames(all_wts1) <- colnames(asset_returns)
# Combing all the values together
portfolio_values1 <- tk_tbl(cbind(all_wts1, portfolio_values1))
## Warning in tk_tbl.data.frame(cbind(all_wts1, portfolio_values1)): Warning: No
## index to preserve. Object otherwise converted to tibble successfully.
We have the weights in each asset with the risk and returns along with the Sharpe ratio of each portfolio. We use daily data to determine the portfolios.
Next lets look at the portfolios that matter the most.
min_var1 <- portfolio_values1[which.min(portfolio_values1$Risk1),]
min_var2 <- portfolio_values1[which.min(portfolio_values1$Risk2),]
min_var3 <- portfolio_values1[which.min(portfolio_values1$Risk3),]
min_var4 <- portfolio_values1[which.min(portfolio_values1$Risk4),]
min_mad <- portfolio_values1[which.min(portfolio_values1$Risk5),]
max_sr1 <- portfolio_values1[which.max(portfolio_values1$SharpeRatio1),]
max_sr2 <- portfolio_values1[which.max(portfolio_values1$SharpeRatio2),]
max_sr3 <- portfolio_values1[which.max(portfolio_values1$SharpeRatio3),]
max_sr4 <- portfolio_values1[which.max(portfolio_values1$SharpeRatio4),]
max_sr5 <- portfolio_values1[which.max(portfolio_values1$SharpeRatio5),]
rbind(min_var1, min_var2, min_var3, min_var4, min_mad, max_sr1, max_sr2, max_sr3, max_sr4, max_sr5)
## # A tibble: 10 × 16
## KO PEP PG V WMT Return Risk1 Risk2 Risk3 Risk4
## <dbl> <dbl> <dbl> <dbl> <dbl> <dbl> <dbl> <dbl> <dbl> <dbl>
## 1 0.312 0.00433 0.118 0.264 0.301 6.86e-5 0.00654 0.00276 0.00414 0.00175
## 2 0.00103 0.0183 0.430 0.313 0.238 2.53e-4 0.00693 0.00269 0.00442 0.00172
## 3 0.219 0.0768 0.109 0.285 0.311 1.32e-4 0.00656 0.00274 0.00411 0.00172
## 4 0.115 0.0296 0.0556 0.0420 0.758 3.88e-4 0.00750 0.00279 0.00452 0.00168
## 5 0.410 0.00253 0.0766 0.268 0.243 -3.88e-5 0.00658 0.00279 0.00423 0.00179
## 6 0.0131 0.0291 0.0277 0.340 0.590 5.41e-4 0.00708 0.00287 0.00438 0.00178
## 7 0.00506 0.0349 0.0168 0.471 0.473 5.48e-4 0.00721 0.00287 0.00454 0.00181
## 8 0.0131 0.0291 0.0277 0.340 0.590 5.41e-4 0.00708 0.00287 0.00438 0.00178
## 9 0.0131 0.0291 0.0277 0.340 0.590 5.41e-4 0.00708 0.00287 0.00438 0.00178
## 10 0.00506 0.0349 0.0168 0.471 0.473 5.48e-4 0.00721 0.00287 0.00454 0.00181
## # ℹ 6 more variables: Risk5 <dbl>, SharpeRatio1 <dbl>, SharpeRatio2 <dbl>,
## # SharpeRatio3 <dbl>, SharpeRatio4 <dbl>, SharpeRatio5 <dbl>
xtable(rbind(min_var1, min_var2, min_var3, min_var4, min_mad, max_sr1, max_sr2, max_sr3, max_sr4, max_sr5), digits = 6)
## % latex table generated in R 4.3.1 by xtable 1.8-4 package
## % Tue Sep 24 19:03:46 2024
## \begin{table}[ht]
## \centering
## \begin{tabular}{rrrrrrrrrrrrrrrrr}
## \hline
## & KO & PEP & PG & V & WMT & Return & Risk1 & Risk2 & Risk3 & Risk4 & Risk5 & SharpeRatio1 & SharpeRatio2 & SharpeRatio3 & SharpeRatio4 & SharpeRatio5 \\
## \hline
## 1 & 0.311847 & 0.004328 & 0.118322 & 0.264130 & 0.301372 & 0.000069 & 0.006543 & 0.002760 & 0.004144 & 0.001748 & 0.005059 & 0.010483 & 0.024856 & 0.016556 & 0.039252 & 0.013561 \\
## 2 & 0.001034 & 0.018301 & 0.430080 & 0.312889 & 0.237696 & 0.000253 & 0.006932 & 0.002689 & 0.004421 & 0.001715 & 0.005338 & 0.036488 & 0.094043 & 0.057202 & 0.147433 & 0.047384 \\
## 3 & 0.218767 & 0.076781 & 0.109321 & 0.284500 & 0.310630 & 0.000132 & 0.006564 & 0.002741 & 0.004109 & 0.001716 & 0.005111 & 0.020072 & 0.048063 & 0.032068 & 0.076790 & 0.025780 \\
## 4 & 0.114640 & 0.029636 & 0.055555 & 0.041969 & 0.758201 & 0.000388 & 0.007499 & 0.002793 & 0.004517 & 0.001682 & 0.005982 & 0.051773 & 0.139019 & 0.085962 & 0.230819 & 0.064901 \\
## 5 & 0.410340 & 0.002532 & 0.076550 & 0.267997 & 0.242581 & -0.000039 & 0.006585 & 0.002791 & 0.004226 & 0.001791 & 0.005043 & -0.005896 & -0.013912 & -0.009186 & -0.021674 & -0.007698 \\
## 6 & 0.013113 & 0.029141 & 0.027676 & 0.339901 & 0.590169 & 0.000541 & 0.007076 & 0.002874 & 0.004383 & 0.001780 & 0.005537 & 0.076468 & 0.188232 & 0.123457 & 0.303899 & 0.097709 \\
## 7 & 0.005057 & 0.034857 & 0.016751 & 0.470698 & 0.472637 & 0.000548 & 0.007206 & 0.002867 & 0.004538 & 0.001805 & 0.005562 & 0.076055 & 0.191184 & 0.120758 & 0.303557 & 0.098525 \\
## 8 & 0.013113 & 0.029141 & 0.027676 & 0.339901 & 0.590169 & 0.000541 & 0.007076 & 0.002874 & 0.004383 & 0.001780 & 0.005537 & 0.076468 & 0.188232 & 0.123457 & 0.303899 & 0.097709 \\
## 9 & 0.013113 & 0.029141 & 0.027676 & 0.339901 & 0.590169 & 0.000541 & 0.007076 & 0.002874 & 0.004383 & 0.001780 & 0.005537 & 0.076468 & 0.188232 & 0.123457 & 0.303899 & 0.097709 \\
## 10 & 0.005057 & 0.034857 & 0.016751 & 0.470698 & 0.472637 & 0.000548 & 0.007206 & 0.002867 & 0.004538 & 0.001805 & 0.005562 & 0.076055 & 0.191184 & 0.120758 & 0.303557 & 0.098525 \\
## \hline
## \end{tabular}
## \end{table}
# change min_var1[1:nassets] and all the indexes after that accordingly
p1 <- cbind(min_var1[1:nasset], 252*min_var1[nasset+1], sqrt(252)*min_var1[nasset+2], sqrt(252)*min_var1[nasset+7])
p2 <- cbind(min_var2[1:nasset], 252*min_var2[nasset+1], sqrt(252)*min_var2[nasset+3], sqrt(252)*min_var2[nasset+8])
p3 <- cbind(min_var3[1:nasset], 252*min_var3[nasset+1], sqrt(252)*min_var3[nasset+4], sqrt(252)*min_var3[nasset+9])
p4 <- cbind(min_var4[1:nasset], 252*min_var4[nasset+1], sqrt(252)*min_var4[nasset+5], sqrt(252)*min_var4[nasset+10])
p5 <- cbind(min_mad[1:nasset], 252*min_mad[nasset+1], sqrt(252)*min_mad[nasset+6], sqrt(252)*min_mad[nasset+11])
xtable(t(rbind(as.numeric(p1), as.numeric(p2), as.numeric(p3), as.numeric(p4), as.numeric(p5))), digits = 5)
## % latex table generated in R 4.3.1 by xtable 1.8-4 package
## % Tue Sep 24 19:03:46 2024
## \begin{table}[ht]
## \centering
## \begin{tabular}{rrrrrr}
## \hline
## & 1 & 2 & 3 & 4 & 5 \\
## \hline
## 1 & 0.31185 & 0.00103 & 0.21877 & 0.11464 & 0.41034 \\
## 2 & 0.00433 & 0.01830 & 0.07678 & 0.02964 & 0.00253 \\
## 3 & 0.11832 & 0.43008 & 0.10932 & 0.05555 & 0.07655 \\
## 4 & 0.26413 & 0.31289 & 0.28450 & 0.04197 & 0.26800 \\
## 5 & 0.30137 & 0.23770 & 0.31063 & 0.75820 & 0.24258 \\
## 6 & 0.01729 & 0.06373 & 0.03320 & 0.09784 & -0.00978 \\
## 7 & 0.10387 & 0.04269 & 0.06522 & 0.02670 & 0.08006 \\
## 8 & 0.16642 & 1.49289 & 0.50907 & 3.66414 & -0.12220 \\
## \hline
## \end{tabular}
## \end{table}
# change max_sr[1:nassets] and all the indexes after that accordingly
p1 <- cbind(max_sr1[1:nasset], 252*max_sr1[nasset+1], sqrt(252)*max_sr1[nasset+2], sqrt(252)*max_sr1[nasset+7])
p2 <- cbind(max_sr2[1:nasset], 252*max_sr2[nasset+1], sqrt(252)*max_sr2[nasset+3], sqrt(252)*max_sr2[nasset+8])
p3 <- cbind(max_sr3[1:nasset], 252*max_sr3[nasset+1], sqrt(252)*max_sr3[nasset+4], sqrt(252)*max_sr3[nasset+9])
p4 <- cbind(max_sr4[1:nasset], 252*max_sr4[nasset+1], sqrt(252)*max_sr4[nasset+5], sqrt(252)*max_sr4[nasset+10])
p5 <- cbind(max_sr5[1:nasset], 252*max_sr5[nasset+1], sqrt(252)*max_sr5[nasset+6], sqrt(252)*max_sr5[nasset+11])
xtable(t(rbind(as.numeric(p1), as.numeric(p2), as.numeric(p3), as.numeric(p4), as.numeric(p5))), digits = 5)
## % latex table generated in R 4.3.1 by xtable 1.8-4 package
## % Tue Sep 24 19:03:46 2024
## \begin{table}[ht]
## \centering
## \begin{tabular}{rrrrrr}
## \hline
## & 1 & 2 & 3 & 4 & 5 \\
## \hline
## 1 & 0.01311 & 0.00506 & 0.01311 & 0.01311 & 0.00506 \\
## 2 & 0.02914 & 0.03486 & 0.02914 & 0.02914 & 0.03486 \\
## 3 & 0.02768 & 0.01675 & 0.02768 & 0.02768 & 0.01675 \\
## 4 & 0.33990 & 0.47070 & 0.33990 & 0.33990 & 0.47070 \\
## 5 & 0.59017 & 0.47264 & 0.59017 & 0.59017 & 0.47264 \\
## 6 & 0.13635 & 0.13811 & 0.13635 & 0.13635 & 0.13811 \\
## 7 & 0.11232 & 0.04551 & 0.06957 & 0.02826 & 0.08830 \\
## 8 & 1.21389 & 3.03496 & 1.95982 & 4.82425 & 1.56404 \\
## \hline
## \end{tabular}
## \end{table}
nasset <- ncol(asset_returns)
w1 <- min_var1[, 1:nasset] %>% gather () %>% arrange(desc(value))
w2 <- min_var2[, 1:nasset] %>% gather () %>% arrange(desc(value))
w3 <- min_var3[, 1:nasset] %>% gather () %>% arrange(desc(value))
w4 <- min_var4[, 1:nasset] %>% gather () %>% arrange(desc(value))
w5 <- min_mad[, 1:nasset] %>% gather () %>% arrange(desc(value))
w6 <- max_sr1[, 1:nasset] %>% gather () %>% arrange(desc(value))
w7 <- max_sr2[, 1:nasset] %>% gather () %>% arrange(desc(value))
w8 <- max_sr3[, 1:nasset] %>% gather () %>% arrange(desc(value))
w9 <- max_sr4[, 1:nasset] %>% gather () %>% arrange(desc(value))
w10 <- max_sr5[, 1:nasset] %>% gather () %>% arrange(desc(value))
xtable(cbind(head (w1, 10), head (w2, 10), head (w3, 10), head (w4, 10), head (w5, 10), head (w6, 10), head (w7, 10), head (w8, 10), head (w9, 10), head (w10, 10)), digits = 4)
## % latex table generated in R 4.3.1 by xtable 1.8-4 package
## % Tue Sep 24 19:03:46 2024
## \begin{table}[ht]
## \centering
## \begin{tabular}{rlrlrlrlrlrlrlrlrlrlr}
## \hline
## & key & value & key & value & key & value & key & value & key & value & key & value & key & value & key & value & key & value & key & value \\
## \hline
## 1 & KO & 0.3118 & PG & 0.4301 & WMT & 0.3106 & WMT & 0.7582 & KO & 0.4103 & WMT & 0.5902 & WMT & 0.4726 & WMT & 0.5902 & WMT & 0.5902 & WMT & 0.4726 \\
## 2 & WMT & 0.3014 & V & 0.3129 & V & 0.2845 & KO & 0.1146 & V & 0.2680 & V & 0.3399 & V & 0.4707 & V & 0.3399 & V & 0.3399 & V & 0.4707 \\
## 3 & V & 0.2641 & WMT & 0.2377 & KO & 0.2188 & PG & 0.0556 & WMT & 0.2426 & PEP & 0.0291 & PEP & 0.0349 & PEP & 0.0291 & PEP & 0.0291 & PEP & 0.0349 \\
## 4 & PG & 0.1183 & PEP & 0.0183 & PG & 0.1093 & V & 0.0420 & PG & 0.0766 & PG & 0.0277 & PG & 0.0168 & PG & 0.0277 & PG & 0.0277 & PG & 0.0168 \\
## 5 & PEP & 0.0043 & KO & 0.0010 & PEP & 0.0768 & PEP & 0.0296 & PEP & 0.0025 & KO & 0.0131 & KO & 0.0051 & KO & 0.0131 & KO & 0.0131 & KO & 0.0051 \\
## \hline
## \end{tabular}
## \end{table}
Lets plot the weights of each portfolio. First with the minimum variance portfolio.
p1 <- min_var4 %>%
gather(colnames(asset_returns)[1]:colnames(asset_returns)[nasset], key = Asset,
value = Weights) %>%
mutate(Asset = as.factor(Asset)) %>%
ggplot(aes(x = fct_reorder(Asset,Weights), y = Weights, fill = Asset)) +
geom_bar(stat = 'identity') +
theme_minimal() +
labs(x = 'Assets', y = 'Weights', title = "Minimum Risk Portfolio Weights") +
scale_y_continuous(labels = scales::percent)
ggplotly(p1)
p2 <- max_sr4 %>%
gather(colnames(asset_returns)[1]:colnames(asset_returns)[nasset], key = Asset,
value = Weights) %>%
mutate(Asset = as.factor(Asset)) %>%
ggplot(aes(x = fct_reorder(Asset, Weights), y = Weights, fill = Asset)) +
geom_bar(stat = 'identity') +
theme_minimal() +
labs(x = 'Assets', y = 'Weights', title = "Tangency Portfolio Weights") +
scale_y_continuous(labels = scales::percent)
ggplotly(p2)
#convert daily return, risk, SR to annualized ones
portfolio_values1_annual <- portfolio_values1 %>% mutate(Return = Return * 252) %>% mutate(Risk1 = Risk1 * sqrt(252), Risk2 = Risk2 * sqrt(252), Risk3 = Risk3 * sqrt(252), Risk4 = Risk4 * sqrt(252), Risk5 = Risk5 * sqrt(252)) %>% mutate(SharpeRatio1 = SharpeRatio1 * sqrt(252), SharpeRatio2 = SharpeRatio2 * sqrt(252), SharpeRatio3 = SharpeRatio3 * sqrt(252), SharpeRatio4 = SharpeRatio4 * sqrt(252), SharpeRatio5 = SharpeRatio5 * sqrt(252))
min_var1.a <- portfolio_values1_annual[which.min(portfolio_values1_annual$Risk1),]
min_var2.a <- portfolio_values1_annual[which.min(portfolio_values1_annual$Risk2),]
min_var3.a <- portfolio_values1_annual[which.min(portfolio_values1_annual$Risk3),]
min_var4.a <- portfolio_values1_annual[which.min(portfolio_values1_annual$Risk4),]
min_mad.a <- portfolio_values1_annual[which.min(portfolio_values1_annual$Risk5),]
max_sr1.a <- portfolio_values1_annual[which.max(portfolio_values1_annual$SharpeRatio1),]
max_sr2.a <- portfolio_values1_annual[which.max(portfolio_values1_annual$SharpeRatio2),]
max_sr3.a <- portfolio_values1_annual[which.max(portfolio_values1_annual$SharpeRatio3),]
max_sr4.a <- portfolio_values1_annual[which.max(portfolio_values1_annual$SharpeRatio4),]
max_sr5.a <- portfolio_values1_annual[which.max(portfolio_values1_annual$SharpeRatio5),]
rbind(min_var1.a, min_var2.a, min_var3.a, min_var4.a, min_mad.a, max_sr1.a, max_sr2.a, max_sr3.a, max_sr4.a, max_sr5.a)
## # A tibble: 10 × 16
## KO PEP PG V WMT Return Risk1 Risk2 Risk3 Risk4
## <dbl> <dbl> <dbl> <dbl> <dbl> <dbl> <dbl> <dbl> <dbl> <dbl>
## 1 0.312 0.00433 0.118 0.264 0.301 0.0173 0.104 0.0438 0.0658 0.0277
## 2 0.00103 0.0183 0.430 0.313 0.238 0.0637 0.110 0.0427 0.0702 0.0272
## 3 0.219 0.0768 0.109 0.285 0.311 0.0332 0.104 0.0435 0.0652 0.0272
## 4 0.115 0.0296 0.0556 0.0420 0.758 0.0978 0.119 0.0443 0.0717 0.0267
## 5 0.410 0.00253 0.0766 0.268 0.243 -0.00978 0.105 0.0443 0.0671 0.0284
## 6 0.0131 0.0291 0.0277 0.340 0.590 0.136 0.112 0.0456 0.0696 0.0283
## 7 0.00506 0.0349 0.0168 0.471 0.473 0.138 0.114 0.0455 0.0720 0.0287
## 8 0.0131 0.0291 0.0277 0.340 0.590 0.136 0.112 0.0456 0.0696 0.0283
## 9 0.0131 0.0291 0.0277 0.340 0.590 0.136 0.112 0.0456 0.0696 0.0283
## 10 0.00506 0.0349 0.0168 0.471 0.473 0.138 0.114 0.0455 0.0720 0.0287
## # ℹ 6 more variables: Risk5 <dbl>, SharpeRatio1 <dbl>, SharpeRatio2 <dbl>,
## # SharpeRatio3 <dbl>, SharpeRatio4 <dbl>, SharpeRatio5 <dbl>
p1 <- portfolio_values1_annual %>%
ggplot(aes(x = Risk1, y = Return, color = SharpeRatio1)) +
geom_point(alpha = 0.4)+
theme_classic() +
scale_y_continuous(labels = scales::percent) +
scale_x_continuous(labels = scales::percent) +
labs(x = 'Annualized Risk (SD)',
y = 'Annualized Returns',
title = "Portfolio Optimization & Efficient Frontier") +
geom_point(aes(x = Risk1,
y = Return), data = min_var1.a, color = 'orange') +
geom_point(aes(x = Risk1,
y = Return), data = max_sr1.a, color = 'orange4', shape = 18)
ggplotly(p1)
p2 <- portfolio_values1_annual %>%
ggplot(aes(x = Risk2, y = Return, color = SharpeRatio2)) +
geom_point(alpha = 0.4)+
theme_classic() +
scale_y_continuous(labels = scales::percent) +
scale_x_continuous(labels = scales::percent) +
labs(x = 'Annualized Risk (VEV)',
y = 'Annualized Returns',
title = "Portfolio Optimization & Efficient Frontier") +
geom_point(aes(x = Risk2,
y = Return), data = min_var2.a, color = 'green') +
geom_point(aes(x = Risk2,
y = Return), data = max_sr2.a, color = 'green4', shape = 18)
ggplotly(p2)
p3 <- portfolio_values1_annual %>%
ggplot(aes(x = Risk3, y = Return, color = SharpeRatio3)) +
geom_point(alpha = 0.4)+
theme_classic() +
scale_y_continuous(labels = scales::percent) +
scale_x_continuous(labels = scales::percent) +
labs(x = 'Annualized Risk (VES)',
y = 'Annualized Returns',
title = "Portfolio Optimization & Efficient Frontier") +
geom_point(aes(x = Risk3,
y = Return), data = min_var3.a, color = 'red') +
geom_point(aes(x = Risk3,
y = Return), data = max_sr3.a, color = 'red4', shape = 18)
ggplotly(p3)
p4 <- portfolio_values1_annual %>%
ggplot(aes(x = Risk4, y = Return, color = SharpeRatio4)) +
geom_point(alpha = 0.4)+
theme_classic() +
scale_y_continuous(labels = scales::percent) +
scale_x_continuous(labels = scales::percent) +
labs(x = 'Annualized Risk (VESV)',
y = 'Annualized Returns',
title = "Portfolio Optimization & Efficient Frontier") +
geom_point(aes(x = Risk4,
y = Return), data = min_var4.a, color = 'purple') +
geom_point(aes(x = Risk4,
y = Return), data = max_sr4.a, color = 'purple4', shape = 18)
ggplotly(p4)
p5 <- portfolio_values1_annual %>%
ggplot(aes(x = Risk5, y = Return, color = SharpeRatio5)) +
geom_point(alpha = 0.4)+
theme_classic() +
scale_y_continuous(labels = scales::percent) +
scale_x_continuous(labels = scales::percent) +
labs(x = 'Annualized Risk (MAD)',
y = 'Annualized Returns',
title = "Portfolio Optimization & Efficient Frontier") +
geom_point(aes(x = Risk5,
y = Return), data = min_mad.a, color = 'blue') +
geom_point(aes(x = Risk5,
y = Return), data = max_sr5.a, color = 'blue4', shape = 18)
ggplotly(p5)
MVP1 <- as.matrix(test)%*%as.vector(as.numeric(min_var1[1:nasset]))
MVP2 <- as.matrix(test)%*%as.vector(as.numeric(min_var2[1:nasset]))
MVP3 <- as.matrix(test)%*%as.vector(as.numeric(min_var3[1:nasset]))
MVP4 <- as.matrix(test)%*%as.vector(as.numeric(min_var4[1:nasset]))
MVP5 <- as.matrix(test)%*%as.vector(as.numeric(min_mad[1:nasset]))
TP1<-as.matrix(test)%*%as.vector(as.numeric(max_sr1[1:nasset]))
TP2<-as.matrix(test)%*%as.vector(as.numeric(max_sr2[1:nasset]))
TP3<-as.matrix(test)%*%as.vector(as.numeric(max_sr3[1:nasset]))
TP4<-as.matrix(test)%*%as.vector(as.numeric(max_sr4[1:nasset]))
TP5<-as.matrix(test)%*%as.vector(as.numeric(max_sr5[1:nasset]))
EWQ<-as.matrix(test)%*%as.vector(rep(1/nasset, nasset))
assets <- c("MVP1", "MVP2", "MVP3", "MVP4", "MVP5", "TP1", "TP2", "TP3", "TP4", "TP5", "EWQ")
#Portfolios <- merge(test[, 1], cumsum(MVP1), cumsum(MVP2), cumsum(MVP3), cumsum(MVP4), cumsum(MVP5), cumsum(TP1), cumsum(TP2), cumsum(TP3), cumsum(TP4), cumsum(TP5), cumsum(EWQ))[, -c(1)]
Portfolios <- cbind.data.frame(cumsum(MVP1), cumsum(MVP2), cumsum(MVP3), cumsum(MVP4), cumsum(MVP5), cumsum(TP1), cumsum(TP2), cumsum(TP3), cumsum(TP4), cumsum(TP5), cumsum(EWQ))
colnames(Portfolios) <- assets
# Define start and end dates
start_date <- as.Date("2023-01-01")
end_date <- as.Date("2023-12-31")
# Create a sequence of dates
date_sequence <- seq(start_date, end_date, by = "day")
#date_sequence
# Number of last values to select
nTemp <- nrow(Portfolios)
# Select the last 'n' values from the vector
TestDates <- date_sequence[(length(date_sequence) - nTemp + 1):length(date_sequence)]
#TestDates
row.names(Portfolios) <- TestDates
dygraph(Portfolios, main = 'Cummulative Returns for Test Period')%>%
dySeries('MVP1', label = 'MVP', col = "orange") %>%
dySeries('MVP2', label = 'MRP2', col = "green") %>%
dySeries('MVP3', label = 'MRP3', col = "red") %>%
dySeries('MVP4', label = 'MRP4', col = "purple") %>%
dySeries('MVP5', label = 'MRP5', col = "blue") %>%
dySeries('TP1', label = 'TP', col = "orange", drawPoints = TRUE) %>%
dySeries('TP2', label = 'MRRP2', col = "green", drawPoints = TRUE) %>%
dySeries('TP3', label = 'MRRP3', col = "red", drawPoints = TRUE) %>%
dySeries('TP4', label = 'MRRP4', col = "purple", drawPoints = TRUE) %>%
dySeries('TP5', label = 'MRRP5', col = "blue", drawPoints = TRUE) %>%
dySeries('EWQ', label = 'EWQ', col = "black") %>%
dyRangeSelector(height = 30)%>%
dyLegend(width = 500)
CumReturnVolCorr_low_risk <- cumsum(TP2)
CumReturnVolCorr_low_risk
## [1] -4.639318e-03 -7.440187e-03 3.166967e-03 2.612756e-03 5.939964e-03
## [6] 1.091707e-02 2.019764e-02 2.295757e-02 1.682062e-02 6.930669e-03
## [11] 3.223164e-05 2.982756e-03 1.670428e-02 1.985505e-02 5.589305e-03
## [16] -9.851739e-04 1.316528e-02 1.870717e-02 3.018547e-02 4.193978e-02
## [21] 3.997052e-02 4.048823e-02 4.525007e-02 4.071426e-02 3.498427e-02
## [26] 4.884436e-02 5.228105e-02 5.661184e-02 6.460128e-02 2.747079e-02
## [31] 2.687493e-02 2.736956e-02 3.357934e-02 3.323814e-02 3.864550e-02
## [36] 4.025854e-02 4.391224e-02 3.817711e-02 4.235897e-02 3.784524e-02
## [41] 3.405463e-02 3.792603e-02 3.209834e-02 3.180444e-02 2.616107e-02
## [46] 2.935184e-02 3.548650e-02 5.007896e-02 3.648414e-02 3.660335e-02
## [51] 4.481605e-02 4.926100e-02 3.768314e-02 4.582684e-02 4.975757e-02
## [56] 5.070527e-02 5.486775e-02 5.657557e-02 5.692635e-02
mi_DBSCAN_2023_highest_mean <- read.csv("~/Desktop/PO/DBSCAN/MI/2023/mi_DBSCAN_2023_highest_mean.csv")
#remove the date column
asset_prices<-mi_DBSCAN_2023_highest_mean[,-1]
# calculate returns
ret_tidy1 = apply(asset_prices,2, log)
head(ret_tidy1)
## BTC.USD ETH.USD NVDA TSLA XRP.USD
## [1,] 9.721957 7.102317 2.660650 4.683057 -1.067625
## [2,] 9.732891 7.136107 2.690517 4.733036 -1.056145
## [3,] 9.731318 7.131250 2.657151 4.703566 -1.084594
## [4,] 9.738139 7.146283 2.697948 4.727919 -1.065240
## [5,] 9.752464 7.186552 2.748406 4.785573 -1.051710
## [6,] 9.766882 7.197874 2.766227 4.777862 -1.046283
ret_tidy2 = diff(ret_tidy1)
head(ret_tidy2)
## BTC.USD ETH.USD NVDA TSLA XRP.USD
## [1,] 0.010934154 0.033789247 0.029867376 0.049978841 0.01148044
## [2,] -0.001572818 -0.004856888 -0.033366310 -0.029469077 -0.02844903
## [3,] 0.006820792 0.015033458 0.040796803 0.024352155 0.01935358
## [4,] 0.014325077 0.040269095 0.050458473 0.057654579 0.01353075
## [5,] 0.014418134 0.011321725 0.017820750 -0.007711028 0.00542694
## [6,] 0.027621150 0.037696756 0.005766083 0.036109205 0.06320558
ret_tidy = exp (ret_tidy2) - 1 #simple returns
#remove first row
asset_returns <- ret_tidy[-1,]
#no.of assets in the portfolio
nasset<-ncol(asset_returns)
# testing and training data sets (each data set has 252 observations)
# Divide the data set in to 3:1 (75% training and 25% testing)
# testing period - January - September (189 data points)
# training period - October - December (62 data points)
n.total<-252
n.train<- 189
train = asset_returns[1:n.train,]
test = asset_returns[-(1:(n.train)),]
##summary statistics
rhosign<-apply(as.matrix(train), MARGIN=2, FUN=rho.cal)
rhovol<-apply(as.matrix(train), MARGIN=2, FUN=rho.vol)
assetsummary<-data.frame(apply(train, 2, mean), apply(train, 2, sd), rhovol, rhosign, apply(train, 2, skewness),
apply(train, 2, kurtosis))
xtable(assetsummary, digits=4)
## % latex table generated in R 4.3.1 by xtable 1.8-4 package
## % Tue Sep 24 19:03:51 2024
## \begin{table}[ht]
## \centering
## \begin{tabular}{rrrrrrr}
## \hline
## & apply.train..2..mean. & apply.train..2..sd. & rhovol & rhosign & apply.train..2..skewness. & apply.train..2..kurtosis. \\
## \hline
## BTC.USD & 0.0030 & 0.0299 & 0.8520 & 0.6790 & 1.7637 & 9.5856 \\
## ETH.USD & 0.0018 & 0.0303 & 0.8551 & 0.7043 & 0.9948 & 5.3989 \\
## NVDA & 0.0064 & 0.0329 & 0.8519 & 0.6880 & 2.4113 & 14.1147 \\
## TSLA & 0.0050 & 0.0344 & 0.9346 & 0.7674 & 0.2517 & 0.7862 \\
## XRP.USD & 0.0039 & 0.0659 & 0.9197 & 0.4595 & 7.3370 & 77.7697 \\
## \hline
## \end{tabular}
## \end{table}
plot(train, legend.loc=1)
## Warning in plot.window(...): "legend.loc" is not a graphical parameter
## Warning in plot.xy(xy, type, ...): "legend.loc" is not a graphical parameter
## Warning in axis(side = side, at = at, labels = labels, ...): "legend.loc" is
## not a graphical parameter
## Warning in axis(side = side, at = at, labels = labels, ...): "legend.loc" is
## not a graphical parameter
## Warning in box(...): "legend.loc" is not a graphical parameter
## Warning in title(...): "legend.loc" is not a graphical parameter
Lets calculate annualized portfolio return, risk, and gamma from the simulated portfolio returns with portfolio weights. (simulated weights)
## portfolio return, sd and gamma
## w is the random weight
## data = train or test
portfolio_info = function(w, data){
port.data <- data%*%as.vector(w)
port.cdf <- ecdf(port.data)
port.return <- mean (port.data)
port.sd <- sd (port.data)
port.signrho <- cor (port.data - port.return, sign(port.data - port.return))
# port.signrho3 <- cor (sign(port.data - port.return), (port.data - port.return)^3)
# port.skewrho <- cor (port.data - port.return, (port.data - port.return)^2)
port.volcor <- cor (abs(port.data - port.return), (port.data - port.return)^2) #volatlity correlation
port.skewness <- skewness (port.data) #mu_3/sigma^3
port.kurtosis <- kurtosis (port.data) #excess kurtosis mu_4/sigma^4 - 3
return(c(port.return, port.sd, port.volcor, port.signrho, port.cdf(port.return), port.skewness, port.kurtosis))
}
# In stat matrix and weight matrix nrow = no.of assets in the portfolio (need to change), ncol is fixed to 7 , for loop i in 1:nrow
stat<-matrix(0, nrow = nasset, ncol = 7)
weight<-matrix(0, nrow = nasset, ncol = nasset)
for (i in 1:nasset){
weight[i, ] <- get_weights(nasset)
stat[i, ] <- portfolio_info (weight[i, ], as.matrix(train))
}
xtable(weight, digits = 4)
## % latex table generated in R 4.3.1 by xtable 1.8-4 package
## % Tue Sep 24 19:03:51 2024
## \begin{table}[ht]
## \centering
## \begin{tabular}{rrrrrr}
## \hline
## & 1 & 2 & 3 & 4 & 5 \\
## \hline
## 1 & 0.1038 & 0.4086 & 0.1221 & 0.0529 & 0.3126 \\
## 2 & 0.2108 & 0.3867 & 0.1204 & 0.1009 & 0.1812 \\
## 3 & 0.2584 & 0.1297 & 0.1697 & 0.2690 & 0.1732 \\
## 4 & 0.0524 & 0.4509 & 0.0131 & 0.1751 & 0.3085 \\
## 5 & 0.0176 & 0.2807 & 0.3209 & 0.3283 & 0.0524 \\
## \hline
## \end{tabular}
## \end{table}
xtable(stat, digits = 4)
## % latex table generated in R 4.3.1 by xtable 1.8-4 package
## % Tue Sep 24 19:03:51 2024
## \begin{table}[ht]
## \centering
## \begin{tabular}{rrrrrrrr}
## \hline
## & 1 & 2 & 3 & 4 & 5 & 6 & 7 \\
## \hline
## 1 & 0.0033 & 0.0322 & 0.8555 & 0.6404 & 0.5026 & 3.0462 & 23.5386 \\
## 2 & 0.0033 & 0.0275 & 0.8558 & 0.6942 & 0.5026 & 1.5938 & 8.3968 \\
## 3 & 0.0041 & 0.0255 & 0.8443 & 0.7253 & 0.5450 & 1.3693 & 6.5051 \\
## 4 & 0.0031 & 0.0325 & 0.8571 & 0.6513 & 0.5079 & 2.8657 & 21.4430 \\
## 5 & 0.0044 & 0.0236 & 0.9357 & 0.7798 & 0.5661 & 0.5988 & 0.6458 \\
## \hline
## \end{tabular}
## \end{table}
Check for the portfolio sd can be calcualted by both the formula and sd of the simulated portfolio.
We have everything we need to perform our optimization. All we need now is to run this code on 8000 random portfolios. For that we will use a for loop.
Before we do that, we need to create empty vectors and matrix for storing our values.
#change nasset to no of assets in portfolio
num_port <- 10000
nasset <- nasset
# Creating a matrix to store the weights
all_wts1 <- matrix(nrow = num_port,
ncol = nasset)
# Creating an empty vector to store
# 8000 Portfolio returns
port_returns <- vector('numeric', length = num_port)
# Creating an empty vector to store
# 8000 Portfolio variances
port_risk.var1 <- vector('numeric', length = num_port)
port_risk.var2 <- vector('numeric', length = num_port)
port_risk.var3 <- vector('numeric', length = num_port)
port_risk.var4 <- vector('numeric', length = num_port)
port_risk.mad <- vector('numeric', length = num_port)
Sharpe_ratio.sd1 <- vector('numeric', length = num_port)
Sharpe_ratio.sd2 <- vector('numeric', length = num_port)
Sharpe_ratio.sd3 <- vector('numeric', length = num_port)
Sharpe_ratio.sd4 <- vector('numeric', length = num_port)
Sharpe_ratio.mad <- vector('numeric', length = num_port)
Next lets run the for loop 10000 times.
port.info <- matrix(0, nrow = 10000, ncol = 7)
ptm <- proc.time()
for (i in seq_along(port_returns)) {
wts <- get_weights(nasset)
# Storing weight in the matrix
all_wts1[i,] <- wts
# Portfolio returns
port.info [i, ]<- portfolio_info (wts, as.matrix(train))
# Storing Portfolio Returns values
port_returns[i] <- port.info[i, 1]
# Creating and storing portfolio risk
port_risk.var1 [i] <- port.info[i, 2]
port_risk.var2 [i] <- sqrt(1 - port.info[i, 3]^2)*port.info[i, 2]
port_risk.var3 [i] <- sqrt(1 - port.info[i, 4]^2)*port.info[i, 2]
port_risk.var4 [i] <- sqrt(1 - port.info[i, 3]^2)*sqrt(1 - port.info[i, 4]^2)*port.info[i, 2]
port_risk.mad [i] <- 2*port.info[i, 2]*port.info[i, 4]*sqrt(port.info[i, 5]*(1-port.info[i, 5]))
# Creating and storing Portfolio Sharpe Ratios
# Assuming 0% Risk free rate
Sharpe_ratio.sd1 [i] <- port_returns[i]/port_risk.var1 [i]
Sharpe_ratio.sd2 [i] <- port_returns[i]/port_risk.var2 [i]
Sharpe_ratio.sd3 [i] <- port_returns[i]/port_risk.var3 [i]
Sharpe_ratio.sd4 [i] <- port_returns[i]/port_risk.var4 [i]
Sharpe_ratio.mad [i] <- port_returns[i]/port_risk.mad [i]
}
proc.time()-ptm
## user system elapsed
## 10.041 0.178 11.693
port.info.data <- as.data.frame(port.info)
ggplot(port.info.data, aes(x=V6, y=V1)) + geom_point(color="blue", alpha=0.5) +geom_smooth(color="darkred") + xlab ("Skewness") + ylab ("Return")
## `geom_smooth()` using method = 'gam' and formula = 'y ~ s(x, bs = "cs")'
ggplot(port.info.data, aes(x=V7, y=V1)) + geom_point(color="blue", alpha=0.5) +geom_smooth(color="darkred") + xlab ("Kurtosis") + ylab ("Return")
## `geom_smooth()` using method = 'gam' and formula = 'y ~ s(x, bs = "cs")'
ggplot(port.info.data, aes(x=V3, y=V6)) + geom_point(color="blue", alpha=0.5) +geom_smooth(color="darkred") + xlab ("Volatlity Correlation") + ylab ("Skewness")
## `geom_smooth()` using method = 'gam' and formula = 'y ~ s(x, bs = "cs")'
ggplot(port.info.data, aes(x=V3, y=V7)) + geom_point(color="blue", alpha=0.5) +geom_smooth(color="darkred") + xlab ("Volatlity Correlation") + ylab ("Kurtosis")
## `geom_smooth()` using method = 'gam' and formula = 'y ~ s(x, bs = "cs")'
ggplot(port.info.data, aes(x=V3, y=V1)) + geom_point(color="blue", alpha=0.5) +geom_smooth(color="darkred") + xlab ("Volatlity Correlation") + ylab ("Return")
## `geom_smooth()` using method = 'gam' and formula = 'y ~ s(x, bs = "cs")'
ggplot(port.info.data, aes(x=V3, y=V2)) + geom_point(color="blue", alpha=0.5) +geom_smooth(color="darkred") + xlab ("Volatlity Correlation") + ylab ("Volatility")
## `geom_smooth()` using method = 'gam' and formula = 'y ~ s(x, bs = "cs")'
ggplot(port.info.data, aes(x=V2, y=V1)) + geom_point(color="blue", alpha=0.5) +geom_smooth(color="darkred") + xlab ("Volatlity") + ylab ("Return")
## `geom_smooth()` using method = 'gam' and formula = 'y ~ s(x, bs = "cs")'
ggplot(port.info.data, aes(x=V3, y=V2)) + geom_point(color="blue", alpha=0.5) +geom_smooth(color="darkred") + xlab ("Volatlity Correlation") + ylab ("Volatlity")
## `geom_smooth()` using method = 'gam' and formula = 'y ~ s(x, bs = "cs")'
ggplot(port.info.data, aes(x=V4, y=V2)) + geom_point(color="blue", alpha=0.5) +geom_smooth(color="darkred") + xlab ("Sign Correlation") + ylab ("Volatility")
## `geom_smooth()` using method = 'gam' and formula = 'y ~ s(x, bs = "cs")'
ggplot(port.info.data, aes(x=V4, y=V6)) + geom_point(color="blue", alpha=0.5) +geom_smooth(color="darkred") + xlab ("Sign Correlation") + ylab ("Skewness")
## `geom_smooth()` using method = 'gam' and formula = 'y ~ s(x, bs = "cs")'
ggplot(port.info.data, aes(x=V4, y=V7)) + geom_point(color="blue", alpha=0.5) +geom_smooth(color="darkred") + xlab ("Sign Correlation") + ylab ("Kurtosis")
## `geom_smooth()` using method = 'gam' and formula = 'y ~ s(x, bs = "cs")'
ggplot(port.info.data, aes(x=V4, y=V1)) + geom_point(color="blue", alpha=0.5) +geom_smooth(color="darkred") + xlab ("Sign Correlation") + ylab ("Return")
## `geom_smooth()` using method = 'gam' and formula = 'y ~ s(x, bs = "cs")'
We now create a data table to store all the values together (using sd).
# Storing the values in the table (5 columns and 8000 rows)
portfolio_values1 <- tibble(Return = port_returns,
Risk1 = port_risk.var1,
Risk2 = port_risk.var2,
Risk3 = port_risk.var3,
Risk4 = port_risk.var4,
Risk5 = port_risk.mad,
SharpeRatio1 = Sharpe_ratio.sd1,
SharpeRatio2 = Sharpe_ratio.sd2,
SharpeRatio3 = Sharpe_ratio.sd3,
SharpeRatio4 = Sharpe_ratio.sd4,
SharpeRatio5 = Sharpe_ratio.mad,
)
# Converting matrix to a tibble and changing column names
all_wts1 <- tk_tbl(all_wts1)
## Warning in tk_tbl.data.frame(as.data.frame(data), preserve_index, rename_index,
## : Warning: No index to preserve. Object otherwise converted to tibble
## successfully.
colnames(all_wts1) <- colnames(asset_returns)
# Combing all the values together
portfolio_values1 <- tk_tbl(cbind(all_wts1, portfolio_values1))
## Warning in tk_tbl.data.frame(cbind(all_wts1, portfolio_values1)): Warning: No
## index to preserve. Object otherwise converted to tibble successfully.
We have the weights in each asset with the risk and returns along with the Sharpe ratio of each portfolio. We use daily data to determine the portfolios.
Next lets look at the portfolios that matter the most.
min_var1 <- portfolio_values1[which.min(portfolio_values1$Risk1),]
min_var2 <- portfolio_values1[which.min(portfolio_values1$Risk2),]
min_var3 <- portfolio_values1[which.min(portfolio_values1$Risk3),]
min_var4 <- portfolio_values1[which.min(portfolio_values1$Risk4),]
min_mad <- portfolio_values1[which.min(portfolio_values1$Risk5),]
max_sr1 <- portfolio_values1[which.max(portfolio_values1$SharpeRatio1),]
max_sr2 <- portfolio_values1[which.max(portfolio_values1$SharpeRatio2),]
max_sr3 <- portfolio_values1[which.max(portfolio_values1$SharpeRatio3),]
max_sr4 <- portfolio_values1[which.max(portfolio_values1$SharpeRatio4),]
max_sr5 <- portfolio_values1[which.max(portfolio_values1$SharpeRatio5),]
rbind(min_var1, min_var2, min_var3, min_var4, min_mad, max_sr1, max_sr2, max_sr3, max_sr4, max_sr5)
## # A tibble: 10 × 16
## BTC.USD ETH.USD NVDA TSLA XRP.USD Return Risk1 Risk2 Risk3 Risk4
## <dbl> <dbl> <dbl> <dbl> <dbl> <dbl> <dbl> <dbl> <dbl> <dbl>
## 1 0.257 0.231 0.282 0.227 0.00297 0.00412 0.0224 0.00936 0.0141 0.00589
## 2 0.0332 0.292 0.259 0.395 0.0208 0.00432 0.0235 0.00728 0.0145 0.00449
## 3 0.173 0.218 0.305 0.303 0.00123 0.00437 0.0227 0.00817 0.0139 0.00498
## 4 0.0356 0.251 0.256 0.452 0.00485 0.00446 0.0241 0.00732 0.0147 0.00448
## 5 0.402 0.133 0.321 0.139 0.00392 0.00421 0.0226 0.0103 0.0148 0.00672
## 6 0.285 0.0104 0.500 0.167 0.0377 0.00505 0.0237 0.0117 0.0155 0.00764
## 7 0.293 0.00816 0.213 0.454 0.0319 0.00464 0.0241 0.00732 0.0149 0.00452
## 8 0.313 0.00404 0.399 0.265 0.0192 0.00489 0.0232 0.00969 0.0145 0.00606
## 9 0.293 0.00816 0.213 0.454 0.0319 0.00464 0.0241 0.00732 0.0149 0.00452
## 10 0.0913 0.00834 0.645 0.238 0.0173 0.00567 0.0267 0.0140 0.0181 0.00948
## # ℹ 6 more variables: Risk5 <dbl>, SharpeRatio1 <dbl>, SharpeRatio2 <dbl>,
## # SharpeRatio3 <dbl>, SharpeRatio4 <dbl>, SharpeRatio5 <dbl>
xtable(rbind(min_var1, min_var2, min_var3, min_var4, min_mad, max_sr1, max_sr2, max_sr3, max_sr4, max_sr5), digits = 6)
## % latex table generated in R 4.3.1 by xtable 1.8-4 package
## % Tue Sep 24 19:04:19 2024
## \begin{table}[ht]
## \centering
## \begin{tabular}{rrrrrrrrrrrrrrrrr}
## \hline
## & BTC.USD & ETH.USD & NVDA & TSLA & XRP.USD & Return & Risk1 & Risk2 & Risk3 & Risk4 & Risk5 & SharpeRatio1 & SharpeRatio2 & SharpeRatio3 & SharpeRatio4 & SharpeRatio5 \\
## \hline
## 1 & 0.256775 & 0.230999 & 0.282050 & 0.227205 & 0.002971 & 0.004125 & 0.022443 & 0.009360 & 0.014123 & 0.005890 & 0.017235 & 0.183792 & 0.440693 & 0.292067 & 0.700313 & 0.239320 \\
## 2 & 0.033232 & 0.292091 & 0.259037 & 0.394862 & 0.020778 & 0.004317 & 0.023550 & 0.007276 & 0.014537 & 0.004491 & 0.018390 & 0.183297 & 0.593275 & 0.296945 & 0.961117 & 0.234726 \\
## 3 & 0.172600 & 0.217724 & 0.305014 & 0.303434 & 0.001228 & 0.004368 & 0.022711 & 0.008165 & 0.013864 & 0.004984 & 0.017641 & 0.192319 & 0.534931 & 0.315059 & 0.876326 & 0.247595 \\
## 4 & 0.035617 & 0.250968 & 0.256470 & 0.452096 & 0.004848 & 0.004458 & 0.024064 & 0.007317 & 0.014730 & 0.004479 & 0.018833 & 0.185257 & 0.609225 & 0.302635 & 0.995229 & 0.236709 \\
## 5 & 0.401948 & 0.133398 & 0.321261 & 0.139477 & 0.003916 & 0.004207 & 0.022615 & 0.010285 & 0.014776 & 0.006720 & 0.017034 & 0.186015 & 0.409027 & 0.284701 & 0.626028 & 0.246965 \\
## 6 & 0.284722 & 0.010400 & 0.499753 & 0.167450 & 0.037674 & 0.005049 & 0.023739 & 0.011684 & 0.015513 & 0.007635 & 0.017812 & 0.212677 & 0.432107 & 0.325461 & 0.661255 & 0.283454 \\
## 7 & 0.292645 & 0.008162 & 0.213163 & 0.454084 & 0.031946 & 0.004639 & 0.024073 & 0.007318 & 0.014882 & 0.004524 & 0.018781 & 0.192711 & 0.633943 & 0.311723 & 1.025448 & 0.247011 \\
## 8 & 0.312931 & 0.004036 & 0.398760 & 0.265056 & 0.019218 & 0.004891 & 0.023174 & 0.009688 & 0.014486 & 0.006056 & 0.017810 & 0.211035 & 0.504778 & 0.337593 & 0.807493 & 0.274592 \\
## 9 & 0.292645 & 0.008162 & 0.213163 & 0.454084 & 0.031946 & 0.004639 & 0.024073 & 0.007318 & 0.014882 & 0.004524 & 0.018781 & 0.192711 & 0.633943 & 0.311723 & 1.025448 & 0.247011 \\
## 10 & 0.091271 & 0.008342 & 0.644655 & 0.238426 & 0.017306 & 0.005665 & 0.026717 & 0.013975 & 0.018120 & 0.009478 & 0.019571 & 0.212046 & 0.405380 & 0.312645 & 0.597701 & 0.289471 \\
## \hline
## \end{tabular}
## \end{table}
# change min_var1[1:nassets] and all the indexes after that accordingly
p1 <- cbind(min_var1[1:nasset], 252*min_var1[nasset+1], sqrt(252)*min_var1[nasset+2], sqrt(252)*min_var1[nasset+7])
p2 <- cbind(min_var2[1:nasset], 252*min_var2[nasset+1], sqrt(252)*min_var2[nasset+3], sqrt(252)*min_var2[nasset+8])
p3 <- cbind(min_var3[1:nasset], 252*min_var3[nasset+1], sqrt(252)*min_var3[nasset+4], sqrt(252)*min_var3[nasset+9])
p4 <- cbind(min_var4[1:nasset], 252*min_var4[nasset+1], sqrt(252)*min_var4[nasset+5], sqrt(252)*min_var4[nasset+10])
p5 <- cbind(min_mad[1:nasset], 252*min_mad[nasset+1], sqrt(252)*min_mad[nasset+6], sqrt(252)*min_mad[nasset+11])
xtable(t(rbind(as.numeric(p1), as.numeric(p2), as.numeric(p3), as.numeric(p4), as.numeric(p5))), digits = 5)
## % latex table generated in R 4.3.1 by xtable 1.8-4 package
## % Tue Sep 24 19:04:19 2024
## \begin{table}[ht]
## \centering
## \begin{tabular}{rrrrrr}
## \hline
## & 1 & 2 & 3 & 4 & 5 \\
## \hline
## 1 & 0.25677 & 0.03323 & 0.17260 & 0.03562 & 0.40195 \\
## 2 & 0.23100 & 0.29209 & 0.21772 & 0.25097 & 0.13340 \\
## 3 & 0.28205 & 0.25904 & 0.30501 & 0.25647 & 0.32126 \\
## 4 & 0.22721 & 0.39486 & 0.30343 & 0.45210 & 0.13948 \\
## 5 & 0.00297 & 0.02078 & 0.00123 & 0.00485 & 0.00392 \\
## 6 & 1.03945 & 1.08779 & 1.10069 & 1.12340 & 1.06010 \\
## 7 & 0.35627 & 0.11550 & 0.22008 & 0.07111 & 0.27040 \\
## 8 & 2.91761 & 9.41794 & 5.00140 & 15.79877 & 3.92044 \\
## \hline
## \end{tabular}
## \end{table}
# change max_sr[1:nassets] and all the indexes after that accordingly
p1 <- cbind(max_sr1[1:nasset], 252*max_sr1[nasset+1], sqrt(252)*max_sr1[nasset+2], sqrt(252)*max_sr1[nasset+7])
p2 <- cbind(max_sr2[1:nasset], 252*max_sr2[nasset+1], sqrt(252)*max_sr2[nasset+3], sqrt(252)*max_sr2[nasset+8])
p3 <- cbind(max_sr3[1:nasset], 252*max_sr3[nasset+1], sqrt(252)*max_sr3[nasset+4], sqrt(252)*max_sr3[nasset+9])
p4 <- cbind(max_sr4[1:nasset], 252*max_sr4[nasset+1], sqrt(252)*max_sr4[nasset+5], sqrt(252)*max_sr4[nasset+10])
p5 <- cbind(max_sr5[1:nasset], 252*max_sr5[nasset+1], sqrt(252)*max_sr5[nasset+6], sqrt(252)*max_sr5[nasset+11])
xtable(t(rbind(as.numeric(p1), as.numeric(p2), as.numeric(p3), as.numeric(p4), as.numeric(p5))), digits = 5)
## % latex table generated in R 4.3.1 by xtable 1.8-4 package
## % Tue Sep 24 19:04:19 2024
## \begin{table}[ht]
## \centering
## \begin{tabular}{rrrrrr}
## \hline
## & 1 & 2 & 3 & 4 & 5 \\
## \hline
## 1 & 0.28472 & 0.29264 & 0.31293 & 0.29264 & 0.09127 \\
## 2 & 0.01040 & 0.00816 & 0.00404 & 0.00816 & 0.00834 \\
## 3 & 0.49975 & 0.21316 & 0.39876 & 0.21316 & 0.64466 \\
## 4 & 0.16745 & 0.45408 & 0.26506 & 0.45408 & 0.23843 \\
## 5 & 0.03767 & 0.03195 & 0.01922 & 0.03195 & 0.01731 \\
## 6 & 1.27230 & 1.16907 & 1.23241 & 1.16907 & 1.42764 \\
## 7 & 0.37685 & 0.11617 & 0.22997 & 0.07182 & 0.31068 \\
## 8 & 3.37615 & 10.06353 & 5.35912 & 16.27848 & 4.59521 \\
## \hline
## \end{tabular}
## \end{table}
nasset <- ncol(asset_returns)
w1 <- min_var1[, 1:nasset] %>% gather () %>% arrange(desc(value))
w2 <- min_var2[, 1:nasset] %>% gather () %>% arrange(desc(value))
w3 <- min_var3[, 1:nasset] %>% gather () %>% arrange(desc(value))
w4 <- min_var4[, 1:nasset] %>% gather () %>% arrange(desc(value))
w5 <- min_mad[, 1:nasset] %>% gather () %>% arrange(desc(value))
w6 <- max_sr1[, 1:nasset] %>% gather () %>% arrange(desc(value))
w7 <- max_sr2[, 1:nasset] %>% gather () %>% arrange(desc(value))
w8 <- max_sr3[, 1:nasset] %>% gather () %>% arrange(desc(value))
w9 <- max_sr4[, 1:nasset] %>% gather () %>% arrange(desc(value))
w10 <- max_sr5[, 1:nasset] %>% gather () %>% arrange(desc(value))
xtable(cbind(head (w1, 10), head (w2, 10), head (w3, 10), head (w4, 10), head (w5, 10), head (w6, 10), head (w7, 10), head (w8, 10), head (w9, 10), head (w10, 10)), digits = 4)
## % latex table generated in R 4.3.1 by xtable 1.8-4 package
## % Tue Sep 24 19:04:19 2024
## \begin{table}[ht]
## \centering
## \begin{tabular}{rlrlrlrlrlrlrlrlrlrlr}
## \hline
## & key & value & key & value & key & value & key & value & key & value & key & value & key & value & key & value & key & value & key & value \\
## \hline
## 1 & NVDA & 0.2821 & TSLA & 0.3949 & NVDA & 0.3050 & TSLA & 0.4521 & BTC.USD & 0.4019 & NVDA & 0.4998 & TSLA & 0.4541 & NVDA & 0.3988 & TSLA & 0.4541 & NVDA & 0.6447 \\
## 2 & BTC.USD & 0.2568 & ETH.USD & 0.2921 & TSLA & 0.3034 & NVDA & 0.2565 & NVDA & 0.3213 & BTC.USD & 0.2847 & BTC.USD & 0.2926 & BTC.USD & 0.3129 & BTC.USD & 0.2926 & TSLA & 0.2384 \\
## 3 & ETH.USD & 0.2310 & NVDA & 0.2590 & ETH.USD & 0.2177 & ETH.USD & 0.2510 & TSLA & 0.1395 & TSLA & 0.1675 & NVDA & 0.2132 & TSLA & 0.2651 & NVDA & 0.2132 & BTC.USD & 0.0913 \\
## 4 & TSLA & 0.2272 & BTC.USD & 0.0332 & BTC.USD & 0.1726 & BTC.USD & 0.0356 & ETH.USD & 0.1334 & XRP.USD & 0.0377 & XRP.USD & 0.0319 & XRP.USD & 0.0192 & XRP.USD & 0.0319 & XRP.USD & 0.0173 \\
## 5 & XRP.USD & 0.0030 & XRP.USD & 0.0208 & XRP.USD & 0.0012 & XRP.USD & 0.0048 & XRP.USD & 0.0039 & ETH.USD & 0.0104 & ETH.USD & 0.0082 & ETH.USD & 0.0040 & ETH.USD & 0.0082 & ETH.USD & 0.0083 \\
## \hline
## \end{tabular}
## \end{table}
Lets plot the weights of each portfolio. First with the minimum variance portfolio.
p1 <- min_var4 %>%
gather(colnames(asset_returns)[1]:colnames(asset_returns)[nasset], key = Asset,
value = Weights) %>%
mutate(Asset = as.factor(Asset)) %>%
ggplot(aes(x = fct_reorder(Asset,Weights), y = Weights, fill = Asset)) +
geom_bar(stat = 'identity') +
theme_minimal() +
labs(x = 'Assets', y = 'Weights', title = "Minimum Risk Portfolio Weights") +
scale_y_continuous(labels = scales::percent)
ggplotly(p1)
p2 <- max_sr4 %>%
gather(colnames(asset_returns)[1]:colnames(asset_returns)[nasset], key = Asset,
value = Weights) %>%
mutate(Asset = as.factor(Asset)) %>%
ggplot(aes(x = fct_reorder(Asset, Weights), y = Weights, fill = Asset)) +
geom_bar(stat = 'identity') +
theme_minimal() +
labs(x = 'Assets', y = 'Weights', title = "Tangency Portfolio Weights") +
scale_y_continuous(labels = scales::percent)
ggplotly(p2)
#convert daily return, risk, SR to annualized ones
portfolio_values1_annual <- portfolio_values1 %>% mutate(Return = Return * 252) %>% mutate(Risk1 = Risk1 * sqrt(252), Risk2 = Risk2 * sqrt(252), Risk3 = Risk3 * sqrt(252), Risk4 = Risk4 * sqrt(252), Risk5 = Risk5 * sqrt(252)) %>% mutate(SharpeRatio1 = SharpeRatio1 * sqrt(252), SharpeRatio2 = SharpeRatio2 * sqrt(252), SharpeRatio3 = SharpeRatio3 * sqrt(252), SharpeRatio4 = SharpeRatio4 * sqrt(252), SharpeRatio5 = SharpeRatio5 * sqrt(252))
min_var1.a <- portfolio_values1_annual[which.min(portfolio_values1_annual$Risk1),]
min_var2.a <- portfolio_values1_annual[which.min(portfolio_values1_annual$Risk2),]
min_var3.a <- portfolio_values1_annual[which.min(portfolio_values1_annual$Risk3),]
min_var4.a <- portfolio_values1_annual[which.min(portfolio_values1_annual$Risk4),]
min_mad.a <- portfolio_values1_annual[which.min(portfolio_values1_annual$Risk5),]
max_sr1.a <- portfolio_values1_annual[which.max(portfolio_values1_annual$SharpeRatio1),]
max_sr2.a <- portfolio_values1_annual[which.max(portfolio_values1_annual$SharpeRatio2),]
max_sr3.a <- portfolio_values1_annual[which.max(portfolio_values1_annual$SharpeRatio3),]
max_sr4.a <- portfolio_values1_annual[which.max(portfolio_values1_annual$SharpeRatio4),]
max_sr5.a <- portfolio_values1_annual[which.max(portfolio_values1_annual$SharpeRatio5),]
rbind(min_var1.a, min_var2.a, min_var3.a, min_var4.a, min_mad.a, max_sr1.a, max_sr2.a, max_sr3.a, max_sr4.a, max_sr5.a)
## # A tibble: 10 × 16
## BTC.USD ETH.USD NVDA TSLA XRP.USD Return Risk1 Risk2 Risk3 Risk4 Risk5
## <dbl> <dbl> <dbl> <dbl> <dbl> <dbl> <dbl> <dbl> <dbl> <dbl> <dbl>
## 1 0.257 0.231 0.282 0.227 0.00297 1.04 0.356 0.149 0.224 0.0935 0.274
## 2 0.0332 0.292 0.259 0.395 0.0208 1.09 0.374 0.116 0.231 0.0713 0.292
## 3 0.173 0.218 0.305 0.303 0.00123 1.10 0.361 0.130 0.220 0.0791 0.280
## 4 0.0356 0.251 0.256 0.452 0.00485 1.12 0.382 0.116 0.234 0.0711 0.299
## 5 0.402 0.133 0.321 0.139 0.00392 1.06 0.359 0.163 0.235 0.107 0.270
## 6 0.285 0.0104 0.500 0.167 0.0377 1.27 0.377 0.185 0.246 0.121 0.283
## 7 0.293 0.00816 0.213 0.454 0.0319 1.17 0.382 0.116 0.236 0.0718 0.298
## 8 0.313 0.00404 0.399 0.265 0.0192 1.23 0.368 0.154 0.230 0.0961 0.283
## 9 0.293 0.00816 0.213 0.454 0.0319 1.17 0.382 0.116 0.236 0.0718 0.298
## 10 0.0913 0.00834 0.645 0.238 0.0173 1.43 0.424 0.222 0.288 0.150 0.311
## # ℹ 5 more variables: SharpeRatio1 <dbl>, SharpeRatio2 <dbl>,
## # SharpeRatio3 <dbl>, SharpeRatio4 <dbl>, SharpeRatio5 <dbl>
p1 <- portfolio_values1_annual %>%
ggplot(aes(x = Risk1, y = Return, color = SharpeRatio1)) +
geom_point(alpha = 0.4)+
theme_classic() +
scale_y_continuous(labels = scales::percent) +
scale_x_continuous(labels = scales::percent) +
labs(x = 'Annualized Risk (SD)',
y = 'Annualized Returns',
title = "Portfolio Optimization & Efficient Frontier") +
geom_point(aes(x = Risk1,
y = Return), data = min_var1.a, color = 'orange') +
geom_point(aes(x = Risk1,
y = Return), data = max_sr1.a, color = 'orange4', shape = 18)
ggplotly(p1)
p2 <- portfolio_values1_annual %>%
ggplot(aes(x = Risk2, y = Return, color = SharpeRatio2)) +
geom_point(alpha = 0.4)+
theme_classic() +
scale_y_continuous(labels = scales::percent) +
scale_x_continuous(labels = scales::percent) +
labs(x = 'Annualized Risk (VEV)',
y = 'Annualized Returns',
title = "Portfolio Optimization & Efficient Frontier") +
geom_point(aes(x = Risk2,
y = Return), data = min_var2.a, color = 'green') +
geom_point(aes(x = Risk2,
y = Return), data = max_sr2.a, color = 'green4', shape = 18)
ggplotly(p2)
p3 <- portfolio_values1_annual %>%
ggplot(aes(x = Risk3, y = Return, color = SharpeRatio3)) +
geom_point(alpha = 0.4)+
theme_classic() +
scale_y_continuous(labels = scales::percent) +
scale_x_continuous(labels = scales::percent) +
labs(x = 'Annualized Risk (VES)',
y = 'Annualized Returns',
title = "Portfolio Optimization & Efficient Frontier") +
geom_point(aes(x = Risk3,
y = Return), data = min_var3.a, color = 'red') +
geom_point(aes(x = Risk3,
y = Return), data = max_sr3.a, color = 'red4', shape = 18)
ggplotly(p3)
p4 <- portfolio_values1_annual %>%
ggplot(aes(x = Risk4, y = Return, color = SharpeRatio4)) +
geom_point(alpha = 0.4)+
theme_classic() +
scale_y_continuous(labels = scales::percent) +
scale_x_continuous(labels = scales::percent) +
labs(x = 'Annualized Risk (VESV)',
y = 'Annualized Returns',
title = "Portfolio Optimization & Efficient Frontier") +
geom_point(aes(x = Risk4,
y = Return), data = min_var4.a, color = 'purple') +
geom_point(aes(x = Risk4,
y = Return), data = max_sr4.a, color = 'purple4', shape = 18)
ggplotly(p4)
p5 <- portfolio_values1_annual %>%
ggplot(aes(x = Risk5, y = Return, color = SharpeRatio5)) +
geom_point(alpha = 0.4)+
theme_classic() +
scale_y_continuous(labels = scales::percent) +
scale_x_continuous(labels = scales::percent) +
labs(x = 'Annualized Risk (MAD)',
y = 'Annualized Returns',
title = "Portfolio Optimization & Efficient Frontier") +
geom_point(aes(x = Risk5,
y = Return), data = min_mad.a, color = 'blue') +
geom_point(aes(x = Risk5,
y = Return), data = max_sr5.a, color = 'blue4', shape = 18)
ggplotly(p5)
MVP1 <- as.matrix(test)%*%as.vector(as.numeric(min_var1[1:nasset]))
MVP2 <- as.matrix(test)%*%as.vector(as.numeric(min_var2[1:nasset]))
MVP3 <- as.matrix(test)%*%as.vector(as.numeric(min_var3[1:nasset]))
MVP4 <- as.matrix(test)%*%as.vector(as.numeric(min_var4[1:nasset]))
MVP5 <- as.matrix(test)%*%as.vector(as.numeric(min_mad[1:nasset]))
TP1<-as.matrix(test)%*%as.vector(as.numeric(max_sr1[1:nasset]))
TP2<-as.matrix(test)%*%as.vector(as.numeric(max_sr2[1:nasset]))
TP3<-as.matrix(test)%*%as.vector(as.numeric(max_sr3[1:nasset]))
TP4<-as.matrix(test)%*%as.vector(as.numeric(max_sr4[1:nasset]))
TP5<-as.matrix(test)%*%as.vector(as.numeric(max_sr5[1:nasset]))
EWQ<-as.matrix(test)%*%as.vector(rep(1/nasset, nasset))
assets <- c("MVP1", "MVP2", "MVP3", "MVP4", "MVP5", "TP1", "TP2", "TP3", "TP4", "TP5", "EWQ")
#Portfolios <- merge(test[, 1], cumsum(MVP1), cumsum(MVP2), cumsum(MVP3), cumsum(MVP4), cumsum(MVP5), cumsum(TP1), cumsum(TP2), cumsum(TP3), cumsum(TP4), cumsum(TP5), cumsum(EWQ))[, -c(1)]
Portfolios <- cbind.data.frame(cumsum(MVP1), cumsum(MVP2), cumsum(MVP3), cumsum(MVP4), cumsum(MVP5), cumsum(TP1), cumsum(TP2), cumsum(TP3), cumsum(TP4), cumsum(TP5), cumsum(EWQ))
colnames(Portfolios) <- assets
# Define start and end dates
start_date <- as.Date("2023-01-01")
end_date <- as.Date("2023-12-31")
# Create a sequence of dates
date_sequence <- seq(start_date, end_date, by = "day")
#date_sequence
# Number of last values to select
nTemp <- nrow(Portfolios)
# Select the last 'n' values from the vector
TestDates <- date_sequence[(length(date_sequence) - nTemp + 1):length(date_sequence)]
#TestDates
row.names(Portfolios) <- TestDates
dygraph(Portfolios, main = 'Cummulative Returns for Test Period')%>%
dySeries('MVP1', label = 'MVP', col = "orange") %>%
dySeries('MVP2', label = 'MRP2', col = "green") %>%
dySeries('MVP3', label = 'MRP3', col = "red") %>%
dySeries('MVP4', label = 'MRP4', col = "purple") %>%
dySeries('MVP5', label = 'MRP5', col = "blue") %>%
dySeries('TP1', label = 'TP', col = "orange", drawPoints = TRUE) %>%
dySeries('TP2', label = 'MRRP2', col = "green", drawPoints = TRUE) %>%
dySeries('TP3', label = 'MRRP3', col = "red", drawPoints = TRUE) %>%
dySeries('TP4', label = 'MRRP4', col = "purple", drawPoints = TRUE) %>%
dySeries('TP5', label = 'MRRP5', col = "blue", drawPoints = TRUE) %>%
dySeries('EWQ', label = 'EWQ', col = "black") %>%
dyRangeSelector(height = 30)%>%
dyLegend(width = 500)
CumReturnVolCorr_high_mean <- cumsum(TP2)
CumReturnVolCorr_high_mean
## [1] 0.011972446 0.002673659 0.009578821 0.007094417 -0.001172195
## [6] -0.020108848 0.007042081 -0.002915986 -0.034179647 -0.070746572
## [11] -0.081358509 -0.036705311 -0.015805724 -0.028582435 -0.053186258
## [16] -0.051528503 -0.062650233 -0.054007392 -0.027908104 0.001923123
## [21] 0.011047699 0.021367876 0.030387082 0.034946397 0.020429309
## [26] 0.041274994 0.055771810 0.078094156 0.105825591 0.075540357
## [31] 0.079795943 0.094366547 0.088174792 0.085266472 0.086395872
## [36] 0.084952357 0.108561981 0.105262357 0.090451766 0.096121357
## [41] 0.110325282 0.136048639 0.130920750 0.139833729 0.153618456
## [46] 0.119697121 0.120582746 0.137727118 0.162516191 0.160687294
## [51] 0.167999936 0.172307781 0.158379018 0.177731223 0.174790225
## [56] 0.173752633 0.190424909 0.170941457 0.158137652
# Example data
CumReturnVolCorr <- data.frame(
Date = as.character(TestDates),
low_avg_risk = CumReturnVolCorr_low_avg_risk,
low_risk = CumReturnVolCorr_low_risk,
high_mean = CumReturnVolCorr_high_mean
)
library(ggplot2)
# Create the plot with date interval
ggplot(data = CumReturnVolCorr, aes(x = as.Date(Date))) +
geom_line(aes(y = low_avg_risk, color = "low_avg_risk"), lwd = 1.5) +
geom_line(aes(y = low_risk, color = "low_risk"), lwd = 1.5) +
geom_line(aes(y = high_mean, color = "high_mean"), lwd = 1.5) +
labs(y = "Cumulative Return",
x = "Date") +
scale_color_manual(name = "Data",
values = c("low_avg_risk" = "blue",
"low_risk" = "red",
"high_mean" = "green"), # Add color for the new series
labels = c("low_avg_risk" = "lowest average risk",
"low_risk" = "lowest risk",
"high_mean" = "highest mean")) + # Adjust labels
scale_x_date(date_breaks = "1 month", date_labels = "%Y-%m") + # Show dates at monthly intervals
theme_minimal()